Fix alert accessibility

This commit is contained in:
Chocobozzz 2024-09-23 11:22:14 +02:00
parent 2dbb83c11b
commit 2011bc29dd
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
91 changed files with 510 additions and 414 deletions

View File

@ -46,7 +46,7 @@
<div *ngIf="formErrors.body" class="form-error" role="alert">{{ formErrors.body }}</div>
</div>
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<my-alert *ngIf="error" type="danger">{{ error }}</my-alert>
<div class="form-group inputs">
<input
@ -58,7 +58,6 @@
</div>
</form>
<div *ngIf="!isContactFormEnabled()" class="alert alert-danger" i18n>The contact form is not enabled on this instance.</div>
<my-alert *ngIf="!isContactFormEnabled()" type="danger" i18n>The contact form is not enabled on this instance.</my-alert>
</div>
</ng-template>

View File

@ -1,4 +1,6 @@
import { NgClass, NgIf } from '@angular/common'
import { Component, OnInit, ViewChild } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { Router } from '@angular/router'
import { Notifier, ServerService } from '@app/core'
import {
@ -9,13 +11,12 @@ import {
} from '@app/shared/form-validators/instance-validators'
import { FormReactive } from '@app/shared/shared-forms/form-reactive'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { InstanceService } from '@app/shared/shared-main/instance/instance.service'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
import { HTMLServerConfig, HttpStatusCode } from '@peertube/peertube-models'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgIf, NgClass } from '@angular/common'
import { GlobalIconComponent } from '../../shared/shared-icons/global-icon.component'
import { InstanceService } from '@app/shared/shared-main/instance/instance.service'
type Prefill = {
subject?: string
@ -27,7 +28,7 @@ type Prefill = {
templateUrl: './contact-admin-modal.component.html',
styleUrls: [ './contact-admin-modal.component.scss' ],
standalone: true,
imports: [ GlobalIconComponent, NgIf, FormsModule, ReactiveFormsModule, NgClass ]
imports: [ GlobalIconComponent, NgIf, FormsModule, ReactiveFormsModule, NgClass, AlertComponent ]
})
export class ContactAdminModalComponent extends FormReactive implements OnInit {
@ViewChild('modal', { static: true }) modal: NgbModal

View File

@ -165,7 +165,7 @@
<ng-container ngProjectAs="description">
<span i18n>⚠️ This functionality requires a lot of attention and extra moderation.</span>
<div class="alert pt-alert-primary alert-signup" *ngIf="signupAlertMessage">{{ signupAlertMessage }}</div>
<my-alert type="primary" class="alert-signup" *ngIf="signupAlertMessage">{{ signupAlertMessage }}</my-alert>
</ng-container>
<ng-container ngProjectAs="extra">

View File

@ -1,19 +1,20 @@
import { pairwise } from 'rxjs/operators'
import { SelectOptionsItem } from 'src/types/select-options-item.model'
import { NgClass, NgFor, NgIf } from '@angular/common'
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'
import { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'
import { RouterLink } from '@angular/router'
import { MenuService, ThemeService } from '@app/core'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { HTMLServerConfig } from '@peertube/peertube-models'
import { ConfigService } from '../shared/config.service'
import { PeerTubeTemplateDirective } from '../../../shared/shared-main/common/peertube-template.directive'
import { SelectOptionsComponent } from '../../../shared/shared-forms/select/select-options.component'
import { UserRealQuotaInfoComponent } from '../../shared/user-real-quota-info.component'
import { pairwise } from 'rxjs/operators'
import { SelectOptionsItem } from 'src/types/select-options-item.model'
import { MarkdownTextareaComponent } from '../../../shared/shared-forms/markdown-textarea.component'
import { HelpComponent } from '../../../shared/shared-main/buttons/help.component'
import { PeertubeCheckboxComponent } from '../../../shared/shared-forms/peertube-checkbox.component'
import { SelectCustomValueComponent } from '../../../shared/shared-forms/select/select-custom-value.component'
import { NgFor, NgIf, NgClass } from '@angular/common'
import { RouterLink } from '@angular/router'
import { SelectOptionsComponent } from '../../../shared/shared-forms/select/select-options.component'
import { HelpComponent } from '../../../shared/shared-main/buttons/help.component'
import { PeerTubeTemplateDirective } from '../../../shared/shared-main/common/peertube-template.directive'
import { UserRealQuotaInfoComponent } from '../../shared/user-real-quota-info.component'
import { ConfigService } from '../shared/config.service'
@Component({
selector: 'my-edit-basic-configuration',
@ -33,7 +34,8 @@ import { RouterLink } from '@angular/router'
NgClass,
UserRealQuotaInfoComponent,
SelectOptionsComponent,
PeerTubeTemplateDirective
PeerTubeTemplateDirective,
AlertComponent
]
})
export class EditBasicConfigurationComponent implements OnInit, OnChanges {

View File

@ -1,8 +1,8 @@
<h1 class="visually-hidden" i18n>Configuration</h1>
<div class="alert alert-warning" *ngIf="!isUpdateAllowed()" i18n>
<my-alert type="warning" *ngIf="!isUpdateAllowed()" i18n>
Updating instance configuration from the web interface is disabled by the system administrator.
</div>
</my-alert>
<form role="form" [formGroup]="form">

View File

@ -27,9 +27,11 @@ import {
import { USER_VIDEO_QUOTA_DAILY_VALIDATOR, USER_VIDEO_QUOTA_VALIDATOR } from '@app/shared/form-validators/user-validators'
import { FormReactive } from '@app/shared/shared-forms/form-reactive'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { CustomPageService } from '@app/shared/shared-main/custom-page/custom-page.service'
import { NgbNav, NgbNavContent, NgbNavItem, NgbNavLink, NgbNavLinkBase, NgbNavOutlet } from '@ng-bootstrap/ng-bootstrap'
import { CustomConfig, CustomPage, HTMLServerConfig } from '@peertube/peertube-models'
import merge from 'lodash-es/merge'
import omit from 'lodash-es/omit'
import { forkJoin } from 'rxjs'
import { SelectOptionsItem } from 'src/types/select-options-item.model'
@ -40,7 +42,6 @@ import { EditHomepageComponent } from './edit-homepage.component'
import { EditInstanceInformationComponent } from './edit-instance-information.component'
import { EditLiveConfigurationComponent } from './edit-live-configuration.component'
import { EditVODTranscodingComponent } from './edit-vod-transcoding.component'
import merge from 'lodash-es/merge'
type ComponentCustomConfig = CustomConfig & {
instanceCustomHomepage: CustomPage
@ -67,7 +68,8 @@ type ComponentCustomConfig = CustomConfig & {
EditLiveConfigurationComponent,
EditAdvancedConfigurationComponent,
NgbNavOutlet,
NgFor
NgFor,
AlertComponent
]
})
export class EditCustomConfigComponent extends FormReactive implements OnInit {

View File

@ -26,9 +26,9 @@
</div>
</div>
<div i18n *ngIf="httpEnabled() === false" class="alert alert-warning">
<my-alert i18n *ngIf="httpEnabled() === false" type="warning">
It seems that you are not on a HTTPS server. Your webserver needs to have TLS activated in order to follow servers.
</div>
</my-alert>
<div class="form-group inputs">
<input

View File

@ -7,6 +7,7 @@ import { UNIQUE_HOSTS_OR_HANDLE_VALIDATOR } from '@app/shared/form-validators/ho
import { FormReactive } from '@app/shared/shared-forms/form-reactive'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { InstanceFollowService } from '@app/shared/shared-instance/instance-follow.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
import { splitAndGetNotEmpty } from '@root-helpers/string'
@ -17,7 +18,7 @@ import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.co
templateUrl: './follow-modal.component.html',
styleUrls: [ './follow-modal.component.scss' ],
standalone: true,
imports: [ GlobalIconComponent, FormsModule, ReactiveFormsModule, NgClass, NgIf ]
imports: [ GlobalIconComponent, FormsModule, ReactiveFormsModule, NgClass, NgIf, AlertComponent ]
})
export class FollowModalComponent extends FormReactive implements OnInit {
@ViewChild('modal', { static: true }) modal: NgbModal

View File

@ -13,9 +13,9 @@
<form novalidate [formGroup]="form" (ngSubmit)="processRegistration()">
<div class="modal-body mb-3">
<div i18n *ngIf="!registration.emailVerified" class="alert alert-warning">
<my-alert i18n *ngIf="!registration.emailVerified" type="warning">
Registration email has not been verified. Email delivery has been disabled by default.
</div>
</my-alert>
<div class="description">
<ng-container *ngIf="isAccept()">
@ -27,9 +27,9 @@
An email will be sent to <em>{{ registration.email }}</em> explaining its account has been created with the moderation response you'll write below.
</p>
<div *ngIf="!isEmailEnabled()" class="alert alert-warning" i18n>
<my-alert *ngIf="!isEmailEnabled()" type="warning" i18n>
Emails are not enabled on this instance so PeerTube won't be able to send an email to <em>{{ registration.email }}</em> explaining its account has been created.
</div>
</my-alert>
</ng-container>
<ng-container *ngIf="isReject()">
@ -37,9 +37,9 @@
An email will be sent to <em>{{ registration.email }}</em> explaining its registration request has been <strong>rejected</strong> with the moderation response you'll write below.
</p>
<div *ngIf="!isEmailEnabled()" class="alert alert-warning" i18n>
<my-alert *ngIf="!isEmailEnabled()" type="warning" i18n>
Emails are not enabled on this instance so PeerTube won't be able to send an email to <em>{{ registration.email }}</em> explaining its registration request has been rejected.
</div>
</my-alert>
</ng-container>
</div>

View File

@ -1,22 +1,23 @@
import { NgClass, NgIf } from '@angular/common'
import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { Notifier, ServerService } from '@app/core'
import { FormReactive } from '@app/shared/shared-forms/form-reactive'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
import { UserRegistration } from '@peertube/peertube-models'
import { PeertubeCheckboxComponent } from '../../../shared/shared-forms/peertube-checkbox.component'
import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.component'
import { AdminRegistrationService } from './admin-registration.service'
import { REGISTRATION_MODERATION_RESPONSE_VALIDATOR } from './process-registration-validators'
import { PeertubeCheckboxComponent } from '../../../shared/shared-forms/peertube-checkbox.component'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.component'
import { NgIf, NgClass } from '@angular/common'
@Component({
selector: 'my-process-registration-modal',
templateUrl: './process-registration-modal.component.html',
standalone: true,
imports: [ NgIf, GlobalIconComponent, FormsModule, ReactiveFormsModule, NgClass, PeertubeCheckboxComponent ]
imports: [ NgIf, GlobalIconComponent, FormsModule, ReactiveFormsModule, NgClass, PeertubeCheckboxComponent, AlertComponent ]
})
export class ProcessRegistrationModalComponent extends FormReactive implements OnInit {
@ViewChild('modal', { static: true }) modal: NgbModal

View File

@ -1,4 +1,6 @@
import { NgClass, NgFor, NgIf, NgTemplateOutlet } from '@angular/common'
import { Component, OnInit } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { Router, RouterLink } from '@angular/router'
import { ConfigService } from '@app/+admin/config/shared/config.service'
import { AuthService, Notifier, ScreenService, ServerService } from '@app/core'
@ -13,20 +15,19 @@ import {
USER_VIDEO_QUOTA_VALIDATOR
} from '@app/shared/form-validators/user-validators'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { UserCreate, UserRole } from '@peertube/peertube-models'
import { UserEdit } from './user-edit'
import { BytesPipe } from '../../../../shared/shared-main/common/bytes.pipe'
import { UserPasswordComponent } from './user-password.component'
import { PeertubeCheckboxComponent } from '../../../../shared/shared-forms/peertube-checkbox.component'
import { UserRealQuotaInfoComponent } from '../../../shared/user-real-quota-info.component'
import { SelectCustomValueComponent } from '../../../../shared/shared-forms/select/select-custom-value.component'
import { InputTextComponent } from '../../../../shared/shared-forms/input-text.component'
import { PeerTubeTemplateDirective } from '../../../../shared/shared-main/common/peertube-template.directive'
import { HelpComponent } from '../../../../shared/shared-main/buttons/help.component'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { ActorAvatarEditComponent } from '../../../../shared/shared-actor-image-edit/actor-avatar-edit.component'
import { NgIf, NgTemplateOutlet, NgClass, NgFor } from '@angular/common'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { UserAdminService } from '@app/shared/shared-users/user-admin.service'
import { UserCreate, UserRole } from '@peertube/peertube-models'
import { ActorAvatarEditComponent } from '../../../../shared/shared-actor-image-edit/actor-avatar-edit.component'
import { InputTextComponent } from '../../../../shared/shared-forms/input-text.component'
import { PeertubeCheckboxComponent } from '../../../../shared/shared-forms/peertube-checkbox.component'
import { SelectCustomValueComponent } from '../../../../shared/shared-forms/select/select-custom-value.component'
import { HelpComponent } from '../../../../shared/shared-main/buttons/help.component'
import { BytesPipe } from '../../../../shared/shared-main/common/bytes.pipe'
import { PeerTubeTemplateDirective } from '../../../../shared/shared-main/common/peertube-template.directive'
import { UserRealQuotaInfoComponent } from '../../../shared/user-real-quota-info.component'
import { UserEdit } from './user-edit'
import { UserPasswordComponent } from './user-password.component'
@Component({
selector: 'my-user-create',
@ -49,7 +50,8 @@ import { UserAdminService } from '@app/shared/shared-users/user-admin.service'
UserRealQuotaInfoComponent,
PeertubeCheckboxComponent,
UserPasswordComponent,
BytesPipe
BytesPipe,
AlertComponent
]
})
export class UserCreateComponent extends UserEdit implements OnInit {

View File

@ -57,7 +57,7 @@
</div>
</ng-template>
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<my-alert *ngIf="error" type="danger">{{ error }}</my-alert>
<div class="pt-two-cols d-xxl-none"> <!-- hidden on large screens, as it is then displayed on the right side of the form -->
<div class="col-0 col-xl-3"></div>

View File

@ -1,5 +1,6 @@
import { Subscription } from 'rxjs'
import { NgClass, NgFor, NgIf, NgTemplateOutlet } from '@angular/common'
import { Component, OnDestroy, OnInit } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { ActivatedRoute, Router, RouterLink } from '@angular/router'
import { ConfigService } from '@app/+admin/config/shared/config.service'
import { AuthService, Notifier, ScreenService, ServerService, User, UserService } from '@app/core'
@ -10,21 +11,21 @@ import {
USER_VIDEO_QUOTA_VALIDATOR
} from '@app/shared/form-validators/user-validators'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { User as UserType, UserAdminFlag, UserRole, UserUpdate } from '@peertube/peertube-models'
import { UserEdit } from './user-edit'
import { BytesPipe } from '../../../../shared/shared-main/common/bytes.pipe'
import { UserPasswordComponent } from './user-password.component'
import { PeertubeCheckboxComponent } from '../../../../shared/shared-forms/peertube-checkbox.component'
import { UserRealQuotaInfoComponent } from '../../../shared/user-real-quota-info.component'
import { SelectCustomValueComponent } from '../../../../shared/shared-forms/select/select-custom-value.component'
import { InputTextComponent } from '../../../../shared/shared-forms/input-text.component'
import { PeerTubeTemplateDirective } from '../../../../shared/shared-main/common/peertube-template.directive'
import { HelpComponent } from '../../../../shared/shared-main/buttons/help.component'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { ActorAvatarEditComponent } from '../../../../shared/shared-actor-image-edit/actor-avatar-edit.component'
import { NgIf, NgTemplateOutlet, NgClass, NgFor } from '@angular/common'
import { UserAdminService } from '@app/shared/shared-users/user-admin.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { TwoFactorService } from '@app/shared/shared-users/two-factor.service'
import { UserAdminService } from '@app/shared/shared-users/user-admin.service'
import { UserAdminFlag, UserRole, User as UserType, UserUpdate } from '@peertube/peertube-models'
import { Subscription } from 'rxjs'
import { ActorAvatarEditComponent } from '../../../../shared/shared-actor-image-edit/actor-avatar-edit.component'
import { InputTextComponent } from '../../../../shared/shared-forms/input-text.component'
import { PeertubeCheckboxComponent } from '../../../../shared/shared-forms/peertube-checkbox.component'
import { SelectCustomValueComponent } from '../../../../shared/shared-forms/select/select-custom-value.component'
import { HelpComponent } from '../../../../shared/shared-main/buttons/help.component'
import { BytesPipe } from '../../../../shared/shared-main/common/bytes.pipe'
import { PeerTubeTemplateDirective } from '../../../../shared/shared-main/common/peertube-template.directive'
import { UserRealQuotaInfoComponent } from '../../../shared/user-real-quota-info.component'
import { UserEdit } from './user-edit'
import { UserPasswordComponent } from './user-password.component'
@Component({
selector: 'my-user-update',
@ -47,7 +48,8 @@ import { TwoFactorService } from '@app/shared/shared-users/two-factor.service'
UserRealQuotaInfoComponent,
PeertubeCheckboxComponent,
UserPasswordComponent,
BytesPipe
BytesPipe,
AlertComponent
]
})
export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {

View File

@ -1,8 +1,8 @@
<my-plugin-navigation [pluginType]="pluginType"></my-plugin-navigation>
<div class="alert pt-alert-primary" i18n *ngIf="pluginInstalled">
<my-alert class="mt-3" type="primary" i18n *ngIf="pluginInstalled">
To load your new installed plugins or themes, refresh the page.
</div>
</my-alert>
<div class="result-and-search">
<ng-container *ngIf="!search">

View File

@ -25,7 +25,3 @@
@include margin-left(15px);
}
.alert {
margin-top: 15px;
}

View File

@ -1,18 +1,19 @@
import { Subject } from 'rxjs'
import { debounceTime, distinctUntilChanged } from 'rxjs/operators'
import { NgFor, NgIf } from '@angular/common'
import { Component, OnInit } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { PluginApiService } from '@app/+admin/plugins/shared/plugin-api.service'
import { ComponentPagination, ConfirmService, hasMoreItems, Notifier, PluginService } from '@app/core'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { PeerTubePluginIndex, PluginType, PluginType_Type } from '@peertube/peertube-models'
import { logger } from '@root-helpers/logger'
import { Subject } from 'rxjs'
import { debounceTime, distinctUntilChanged } from 'rxjs/operators'
import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.component'
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
import { EditButtonComponent } from '../../../shared/shared-main/buttons/edit-button.component'
import { PluginCardComponent } from '../shared/plugin-card.component'
import { InfiniteScrollerDirective } from '../../../shared/shared-main/common/infinite-scroller.directive'
import { AutofocusDirective } from '../../../shared/shared-main/common/autofocus.directive'
import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.component'
import { NgIf, NgFor } from '@angular/common'
import { InfiniteScrollerDirective } from '../../../shared/shared-main/common/infinite-scroller.directive'
import { PluginCardComponent } from '../shared/plugin-card.component'
import { PluginNavigationComponent } from '../shared/plugin-navigation.component'
@Component({
@ -29,7 +30,8 @@ import { PluginNavigationComponent } from '../shared/plugin-navigation.component
NgFor,
PluginCardComponent,
EditButtonComponent,
ButtonComponent
ButtonComponent,
AlertComponent
]
})
export class PluginSearchComponent implements OnInit {

View File

@ -15,7 +15,7 @@
<div class="margin-content">
<ng-container *ngIf="!externalAuthError && !isAuthenticatedWithExternalAuth">
<div class="alert pt-alert-primary" role="alert">
<my-alert type="primary">
<h5 class="alert-heading" i18n>
Logging into an account lets you publish content
</h5>
@ -31,19 +31,19 @@
Find yours among multiple instances at: <a class="link-orange" href="https://joinpeertube.org/instances" target="_blank" rel="noopener noreferrer">https://joinpeertube.org/instances</a>.
</p>
}
</div>
</my-alert>
<div class="alert alert-danger" i18n *ngIf="externalAuthError">
<my-alert type="danger" i18n *ngIf="externalAuthError">
Sorry but there was an issue with the external login process. Please <a class="link-orange" routerLink="/about">contact an administrator</a>.
</div>
</my-alert>
<div *ngIf="error" class="alert alert-danger" role="alert">
<my-alert *ngIf="error" type="danger">
{{ error }}
<a *ngIf="error === 'User email is not verified.'" class="ms-1 link-orange" i18n routerLink="/verify-account/ask-send-email">
Request new verification email
</a>
</div>
</my-alert>
<div class="wrapper">
<div class="login-form-and-externals">
@ -137,9 +137,9 @@
<div class="modal-body text-start">
<div *ngIf="isEmailDisabled()" class="alert alert-danger" i18n>
<my-alert *ngIf="isEmailDisabled()" type="danger" i18n>
We are sorry, you cannot recover your password because your instance administrator did not configure the PeerTube email system.
</div>
</my-alert>
<div *ngIf="!isEmailDisabled()" class="mb-4" i18n>
Enter your email address and we will send you a link to reset your password.

View File

@ -25,11 +25,12 @@ input[type=email] {
}
.wrapper,
.alert {
my-alert {
display: block;
max-width: 1200px;
}
.alert {
my-alert {
@include margin(0, auto, 2rem);
}

View File

@ -1,23 +1,24 @@
import { environment } from 'src/environments/environment'
import { NgClass, NgFor, NgIf, NgTemplateOutlet } from '@angular/common'
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { ActivatedRoute, Router, RouterLink } from '@angular/router'
import { AuthService, Notifier, RedirectService, SessionStorageService, UserService } from '@app/core'
import { HooksService } from '@app/core/plugins/hooks.service'
import { LOGIN_PASSWORD_VALIDATOR, LOGIN_USERNAME_VALIDATOR } from '@app/shared/form-validators/login-validators'
import { USER_OTP_TOKEN_VALIDATOR } from '@app/shared/form-validators/user-validators'
import { FormReactive } from '@app/shared/shared-forms/form-reactive'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { InputTextComponent } from '@app/shared/shared-forms/input-text.component'
import { InstanceAboutAccordionComponent } from '@app/shared/shared-instance/instance-about-accordion.component'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { NgbAccordionDirective, NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'
import { getExternalAuthHref } from '@peertube/peertube-core-utils'
import { RegisteredExternalAuthConfig, ServerConfig, ServerErrorCode } from '@peertube/peertube-models'
import { environment } from 'src/environments/environment'
import { GlobalIconComponent } from '../shared/shared-icons/global-icon.component'
import { InstanceBannerComponent } from '../shared/shared-instance/instance-banner.component'
import { AutofocusDirective } from '../shared/shared-main/common/autofocus.directive'
import { PluginSelectorDirective } from '../shared/shared-main/plugins/plugin-selector.directive'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgIf, NgClass, NgTemplateOutlet, NgFor } from '@angular/common'
import { InstanceAboutAccordionComponent } from '@app/shared/shared-instance/instance-about-accordion.component'
import { InputTextComponent } from '@app/shared/shared-forms/input-text.component'
import { FormReactive } from '@app/shared/shared-forms/form-reactive'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
@Component({
selector: 'my-login',
@ -37,7 +38,8 @@ import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.serv
NgFor,
InstanceBannerComponent,
InstanceAboutAccordionComponent,
GlobalIconComponent
GlobalIconComponent,
AlertComponent
]
})

View File

@ -1,6 +1,6 @@
import { of } from 'rxjs'
import { switchMap } from 'rxjs/operators'
import { NgClass, NgIf } from '@angular/common'
import { AfterViewInit, Component, OnInit } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { Router } from '@angular/router'
import { AuthService, HooksService, Notifier } from '@app/core'
import {
@ -10,17 +10,18 @@ import {
VIDEO_CHANNEL_SUPPORT_VALIDATOR
} from '@app/shared/form-validators/video-channel-validators'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { HttpStatusCode, VideoChannelCreate } from '@peertube/peertube-models'
import { VideoChannelEdit } from './video-channel-edit'
import { PeertubeCheckboxComponent } from '../../shared/shared-forms/peertube-checkbox.component'
import { MarkdownTextareaComponent } from '../../shared/shared-forms/markdown-textarea.component'
import { HelpComponent } from '../../shared/shared-main/buttons/help.component'
import { ActorAvatarEditComponent } from '../../shared/shared-actor-image-edit/actor-avatar-edit.component'
import { ActorBannerEditComponent } from '../../shared/shared-actor-image-edit/actor-banner-edit.component'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgIf, NgClass } from '@angular/common'
import { VideoChannel } from '@app/shared/shared-main/channel/video-channel.model'
import { VideoChannelService } from '@app/shared/shared-main/channel/video-channel.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { HttpStatusCode, VideoChannelCreate } from '@peertube/peertube-models'
import { of } from 'rxjs'
import { switchMap } from 'rxjs/operators'
import { ActorAvatarEditComponent } from '../../shared/shared-actor-image-edit/actor-avatar-edit.component'
import { ActorBannerEditComponent } from '../../shared/shared-actor-image-edit/actor-banner-edit.component'
import { MarkdownTextareaComponent } from '../../shared/shared-forms/markdown-textarea.component'
import { PeertubeCheckboxComponent } from '../../shared/shared-forms/peertube-checkbox.component'
import { HelpComponent } from '../../shared/shared-main/buttons/help.component'
import { VideoChannelEdit } from './video-channel-edit'
@Component({
templateUrl: './video-channel-edit.component.html',
@ -35,7 +36,8 @@ import { VideoChannelService } from '@app/shared/shared-main/channel/video-chann
NgClass,
HelpComponent,
MarkdownTextareaComponent,
PeertubeCheckboxComponent
PeertubeCheckboxComponent,
AlertComponent
]
})
export class VideoChannelCreateComponent extends VideoChannelEdit implements OnInit, AfterViewInit {

View File

@ -1,4 +1,4 @@
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<my-alert *ngIf="error" type="danger">{{ error }}</my-alert>
<div class="margin-content pt-4">
<form role="form" (ngSubmit)="formValidated()" [formGroup]="form">

View File

@ -12,6 +12,7 @@ import {
} from '@app/shared/form-validators/video-channel-validators'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { VideoChannelService } from '@app/shared/shared-main/channel/video-channel.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { shallowCopy } from '@peertube/peertube-core-utils'
import { VideoChannelUpdate } from '@peertube/peertube-models'
import { Subscription } from 'rxjs'
@ -36,7 +37,8 @@ import { VideoChannelEdit } from './video-channel-edit'
NgClass,
HelpComponent,
MarkdownTextareaComponent,
PeertubeCheckboxComponent
PeertubeCheckboxComponent,
AlertComponent
]
})
export class VideoChannelUpdateComponent extends VideoChannelEdit implements OnInit, AfterViewInit, OnDestroy {

View File

@ -89,11 +89,11 @@
<div class="modal-body">
<div i18n class="alert alert-warning" *ngIf="hasAlreadyACompletedArchive()">
<my-alert i18n type="warning" *ngIf="hasAlreadyACompletedArchive()">
You already have an active archive. Requesting a new export archive will remove the current one.
</div>
</my-alert>
<div *ngIf="errorInModal" class="alert alert-danger">{{ errorInModal }}</div>
<my-alert *ngIf="errorInModal" type="danger">{{ errorInModal }}</my-alert>
<my-peertube-checkbox
inputName="exportWithVideos" [(ngModel)]="exportWithVideosFiles"

View File

@ -2,6 +2,7 @@ import { DatePipe, NgFor, NgIf } from '@angular/common'
import { Component, Input, OnInit, ViewChild } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { AuthService, ServerService } from '@app/core'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'
import { PeerTubeProblemDocument, ServerErrorCode, UserExport, UserExportState } from '@peertube/peertube-models'
import { concatMap, from, of, switchMap, toArray } from 'rxjs'
@ -15,7 +16,7 @@ import { UserImportExportService } from './user-import-export.service'
templateUrl: './my-account-export.component.html',
styleUrls: [ './my-account-export.component.scss' ],
standalone: true,
imports: [ NgIf, NgFor, GlobalIconComponent, PeertubeCheckboxComponent, FormsModule, DatePipe, BytesPipe ]
imports: [ NgIf, NgFor, GlobalIconComponent, PeertubeCheckboxComponent, FormsModule, DatePipe, BytesPipe, AlertComponent ]
})
export class MyAccountExportComponent implements OnInit {
@ViewChild('exportModal', { static: true }) exportModal: NgbModal

View File

@ -48,9 +48,9 @@
</div>
@if (hasPendingImport()) {
<div i18n class="alert pt-alert-primary">
<my-alert i18n type="primary">
You can't re-import an archive because you already have an import that is currently being processed by PeerTube.
</div>
</my-alert>
} @else {
<my-upload-progress
[isUploading]="uploadingArchive" [uploadPercents]="uploadPercents" [error]="error" [uploaded]="archiveUploadFinished"
@ -58,9 +58,9 @@
>
</my-upload-progress>
<div *ngIf="archiveUploadFinished && !error" class="alert pt-alert-primary" i18n>
<my-alert *ngIf="archiveUploadFinished && !error" type="primary" i18n>
Upload completed. Your archive import will be processed as soon as possible.
</div>
</my-alert>
<div [hidden]="uploadingArchive || archiveUploadFinished" class="button-file form-control" i18n-ngbTooltip ngbTooltip="(extension: .zip)">
<span i18n>Select the archive file to import</span>

View File

@ -6,6 +6,7 @@
@include orange-button;
}
.pt-alert-primary {
my-alert {
display: block;
width: fit-content;
}

View File

@ -3,6 +3,7 @@ import { HttpErrorResponse } from '@angular/common/http'
import { Component, Input, OnDestroy, OnInit } from '@angular/core'
import { AuthService, CanComponentDeactivate, Notifier, ServerService } from '@app/core'
import { buildHTTPErrorResponse, genericUploadErrorHandler, getUploadXRetryConfig } from '@app/helpers'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { BytesPipe } from '@app/shared/shared-main/common/bytes.pipe'
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'
import { HttpStatusCode, UserImport, UserImportState } from '@peertube/peertube-models'
@ -16,7 +17,7 @@ import { UserImportExportService } from './user-import-export.service'
templateUrl: './my-account-import.component.html',
styleUrls: [ './my-account-import.component.scss' ],
standalone: true,
imports: [ NgIf, UploadProgressComponent, NgbTooltip, DatePipe ]
imports: [ NgIf, UploadProgressComponent, NgbTooltip, DatePipe, AlertComponent ]
})
export class MyAccountImportComponent implements OnInit, OnDestroy, CanComponentDeactivate {
@Input() videoQuotaUsed: number

View File

@ -1,5 +1,5 @@
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<div *ngIf="success" class="alert alert-success">{{ success }}</div>
<my-alert *ngIf="error" type="danger">{{ error }}</my-alert>
<my-alert *ngIf="success" type="success">{{ success }}</my-alert>
<div i18n class="pending-email" *ngIf="user.pendingEmail">
<strong>{{ user.pendingEmail }}</strong> is awaiting email verification

View File

@ -5,6 +5,7 @@ import { AuthService, ServerService, UserService } from '@app/core'
import { USER_EMAIL_VALIDATOR, USER_PASSWORD_VALIDATOR } from '@app/shared/form-validators/user-validators'
import { FormReactive } from '@app/shared/shared-forms/form-reactive'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { HttpStatusCode, User } from '@peertube/peertube-models'
import { forkJoin } from 'rxjs'
import { tap } from 'rxjs/operators'
@ -15,7 +16,7 @@ import { InputTextComponent } from '../../../shared/shared-forms/input-text.comp
templateUrl: './my-account-change-email.component.html',
styleUrls: [ './my-account-change-email.component.scss' ],
standalone: true,
imports: [ NgIf, FormsModule, ReactiveFormsModule, NgClass, InputTextComponent ]
imports: [ NgIf, FormsModule, ReactiveFormsModule, NgClass, InputTextComponent, AlertComponent ]
})
export class MyAccountChangeEmailComponent extends FormReactive implements OnInit {
error: string

View File

@ -1,4 +1,4 @@
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<my-alert *ngIf="error" type="danger">{{ error }}</my-alert>
<form role="form" (ngSubmit)="changePassword()" [formGroup]="form">

View File

@ -1,5 +1,6 @@
import { filter } from 'rxjs/operators'
import { NgIf } from '@angular/common'
import { Component, OnInit } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { AuthService, Notifier, UserService } from '@app/core'
import {
USER_CONFIRM_PASSWORD_VALIDATOR,
@ -8,17 +9,17 @@ import {
} from '@app/shared/form-validators/user-validators'
import { FormReactive } from '@app/shared/shared-forms/form-reactive'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { HttpStatusCode, User } from '@peertube/peertube-models'
import { filter } from 'rxjs/operators'
import { InputTextComponent } from '../../../shared/shared-forms/input-text.component'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgIf } from '@angular/common'
@Component({
selector: 'my-account-change-password',
templateUrl: './my-account-change-password.component.html',
styleUrls: [ './my-account-change-password.component.scss' ],
standalone: true,
imports: [ NgIf, FormsModule, ReactiveFormsModule, InputTextComponent ]
imports: [ NgIf, FormsModule, ReactiveFormsModule, InputTextComponent, AlertComponent ]
})
export class MyAccountChangePasswordComponent extends FormReactive implements OnInit {
error: string

View File

@ -1,4 +1,4 @@
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<my-alert *ngIf="error" type="danger">{{ error }}</my-alert>
<form role="form" (ngSubmit)="updateMyProfile()" [formGroup]="form">

View File

@ -5,13 +5,14 @@ import { Notifier, User, UserService } from '@app/core'
import { USER_DESCRIPTION_VALIDATOR, USER_DISPLAY_NAME_REQUIRED_VALIDATOR } from '@app/shared/form-validators/user-validators'
import { FormReactive } from '@app/shared/shared-forms/form-reactive'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
@Component({
selector: 'my-account-profile',
templateUrl: './my-account-profile.component.html',
styleUrls: [ './my-account-profile.component.scss' ],
standalone: true,
imports: [ NgIf, FormsModule, ReactiveFormsModule, NgClass ]
imports: [ NgIf, FormsModule, ReactiveFormsModule, NgClass, AlertComponent ]
})
export class MyAccountProfileComponent extends FormReactive implements OnInit {
@Input() user: User = null

View File

@ -1,4 +1,4 @@
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<my-alert *ngIf="error" type="danger">{{ error }}</my-alert>
<h1>
<my-global-icon iconName="refresh" aria-hidden="true"></my-global-icon>

View File

@ -4,6 +4,7 @@ import { RouterLink } from '@angular/router'
import { AuthService, Notifier, RestPagination, RestTable, ServerService } from '@app/core'
import { VideoChannelSyncService } from '@app/shared/shared-main/channel/video-channel-sync.service'
import { VideoChannelService } from '@app/shared/shared-main/channel/video-channel.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'
import { HTMLServerConfig, VideoChannelSync, VideoChannelSyncState, VideoChannelSyncStateType } from '@peertube/peertube-models'
import { SharedModule, SortMeta } from 'primeng/api'
@ -27,7 +28,8 @@ import { ActionDropdownComponent, DropdownAction } from '../../shared/shared-mai
ActionDropdownComponent,
ActorAvatarComponent,
NgClass,
DatePipe
DatePipe,
AlertComponent
]
})
export class MyVideoChannelSyncsComponent extends RestTable implements OnInit {

View File

@ -1,4 +1,4 @@
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<my-alert *ngIf="error" type="danger">{{ error }}</my-alert>
<div class="pt-two-cols">

View File

@ -9,6 +9,7 @@ import { FormReactive } from '@app/shared/shared-forms/form-reactive'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { VideoChannelSyncService } from '@app/shared/shared-main/channel/video-channel-sync.service'
import { VideoChannelService } from '@app/shared/shared-main/channel/video-channel.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { VideoChannelSyncCreate } from '@peertube/peertube-models'
import { mergeMap } from 'rxjs'
import { SelectChannelItem } from 'src/types'
@ -19,7 +20,7 @@ import { SelectChannelComponent } from '../../../shared/shared-forms/select/sele
templateUrl: './video-channel-sync-edit.component.html',
styleUrls: [ './video-channel-sync-edit.component.scss' ],
standalone: true,
imports: [ NgIf, FormsModule, ReactiveFormsModule, NgClass, SelectChannelComponent ]
imports: [ NgIf, FormsModule, ReactiveFormsModule, NgClass, SelectChannelComponent, AlertComponent ]
})
export class VideoChannelSyncEditComponent extends FormReactive implements OnInit {
error: string

View File

@ -1,4 +1,6 @@
import { NgClass, NgIf } from '@angular/common'
import { Component, OnInit } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { Router, RouterLink } from '@angular/router'
import { AuthService, Notifier, ServerService } from '@app/core'
import { listUserChannelsForSelect } from '@app/helpers'
@ -10,16 +12,15 @@ import {
VIDEO_PLAYLIST_PRIVACY_VALIDATOR
} from '@app/shared/form-validators/video-playlist-validators'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { VideoPlaylistService } from '@app/shared/shared-video-playlist/video-playlist.service'
import { VideoPlaylistCreate, VideoPlaylistPrivacy } from '@peertube/peertube-models'
import { MyVideoPlaylistEdit } from './my-video-playlist-edit'
import { MarkdownTextareaComponent } from '../../shared/shared-forms/markdown-textarea.component'
import { PreviewUploadComponent } from '../../shared/shared-forms/preview-upload.component'
import { SelectChannelComponent } from '../../shared/shared-forms/select/select-channel.component'
import { SelectOptionsComponent } from '../../shared/shared-forms/select/select-options.component'
import { MarkdownTextareaComponent } from '../../shared/shared-forms/markdown-textarea.component'
import { HelpComponent } from '../../shared/shared-main/buttons/help.component'
import { PreviewUploadComponent } from '../../shared/shared-forms/preview-upload.component'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgIf, NgClass } from '@angular/common'
import { VideoPlaylistService } from '@app/shared/shared-video-playlist/video-playlist.service'
import { MyVideoPlaylistEdit } from './my-video-playlist-edit'
@Component({
templateUrl: './my-video-playlist-edit.component.html',
@ -35,7 +36,8 @@ import { VideoPlaylistService } from '@app/shared/shared-video-playlist/video-pl
HelpComponent,
MarkdownTextareaComponent,
SelectOptionsComponent,
SelectChannelComponent
SelectChannelComponent,
AlertComponent
]
})
export class MyVideoPlaylistCreateComponent extends MyVideoPlaylistEdit implements OnInit {

View File

@ -1,4 +1,4 @@
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<my-alert *ngIf="error" type="danger">{{ error }}</my-alert>
<div class="pt-two-cols"> <!-- playlist grid -->
<div class="title-col">

View File

@ -12,6 +12,7 @@ import {
VIDEO_PLAYLIST_PRIVACY_VALIDATOR
} from '@app/shared/form-validators/video-playlist-validators'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { VideoPlaylistService } from '@app/shared/shared-video-playlist/video-playlist.service'
import { VideoPlaylistUpdate } from '@peertube/peertube-models'
import { forkJoin, Subscription } from 'rxjs'
@ -37,7 +38,8 @@ import { MyVideoPlaylistEdit } from './my-video-playlist-edit'
HelpComponent,
MarkdownTextareaComponent,
SelectOptionsComponent,
SelectChannelComponent
SelectChannelComponent,
AlertComponent
]
})
export class MyVideoPlaylistUpdateComponent extends MyVideoPlaylistEdit implements OnInit, OnDestroy {

View File

@ -1,5 +1,3 @@
<div class="root">
<div class="alert alert-danger" *ngIf="error">{{ error }}</div>
<my-alert type="danger" *ngIf="error">{{ error }}</my-alert>
</div>

View File

@ -1,16 +1,17 @@
import { forkJoin } from 'rxjs'
import { NgIf } from '@angular/common'
import { Component, OnInit } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { NgIf } from '@angular/common'
import { Video } from '@app/shared/shared-main/video/video.model'
import { VideoChannel } from '@app/shared/shared-main/channel/video-channel.model'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { Video } from '@app/shared/shared-main/video/video.model'
import { SearchService } from '@app/shared/shared-search/search.service'
import { forkJoin } from 'rxjs'
@Component({
selector: 'my-remote-interaction',
templateUrl: './remote-interaction.component.html',
standalone: true,
imports: [ NgIf ]
imports: [ NgIf, AlertComponent ]
})
export class RemoteInteractionComponent implements OnInit {
error = ''

View File

@ -27,7 +27,7 @@
<div id="search-results-filter" class="results-filter" [ngbCollapse]="isSearchFilterCollapsed" [animation]="true">
<my-search-filters [advancedSearch]="advancedSearch" (filtered)="onFiltered()"></my-search-filters>
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<my-alert *ngIf="error" type="danger">{{ error }}</my-alert>
</div>
</div>

View File

@ -1,25 +1,26 @@
import { forkJoin, Subject, Subscription } from 'rxjs'
import { LinkType } from 'src/types/link.type'
import { NgFor, NgIf, NgTemplateOutlet } from '@angular/common'
import { Component, OnDestroy, OnInit } from '@angular/core'
import { ActivatedRoute, Router, RouterLink } from '@angular/router'
import { AuthService, HooksService, MetaService, Notifier, ServerService, User, UserService } from '@app/core'
import { immutableAssign, SimpleMemoize } from '@app/helpers'
import { validateHost } from '@app/shared/form-validators/host-validators'
import { HTMLServerConfig, SearchTargetType } from '@peertube/peertube-models'
import { NumberFormatterPipe } from '../shared/shared-main/common/number-formatter.pipe'
import { VideoPlaylistMiniatureComponent } from '../shared/shared-video-playlist/video-playlist-miniature.component'
import { MiniatureDisplayOptions, VideoMiniatureComponent } from '../shared/shared-video-miniature/video-miniature.component'
import { SubscribeButtonComponent } from '../shared/shared-user-subscription/subscribe-button.component'
import { ActorAvatarComponent } from '../shared/shared-actor-image/actor-avatar.component'
import { SearchFiltersComponent } from './search-filters.component'
import { NgbCollapse } from '@ng-bootstrap/ng-bootstrap'
import { NgIf, NgFor, NgTemplateOutlet } from '@angular/common'
import { InfiniteScrollerDirective } from '../shared/shared-main/common/infinite-scroller.directive'
import { VideoChannel } from '@app/shared/shared-main/channel/video-channel.model'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { Video } from '@app/shared/shared-main/video/video.model'
import { VideoPlaylist } from '@app/shared/shared-video-playlist/video-playlist.model'
import { AdvancedSearch } from '@app/shared/shared-search/advanced-search.model'
import { SearchService } from '@app/shared/shared-search/search.service'
import { VideoPlaylist } from '@app/shared/shared-video-playlist/video-playlist.model'
import { NgbCollapse } from '@ng-bootstrap/ng-bootstrap'
import { HTMLServerConfig, SearchTargetType } from '@peertube/peertube-models'
import { forkJoin, Subject, Subscription } from 'rxjs'
import { LinkType } from 'src/types/link.type'
import { ActorAvatarComponent } from '../shared/shared-actor-image/actor-avatar.component'
import { InfiniteScrollerDirective } from '../shared/shared-main/common/infinite-scroller.directive'
import { NumberFormatterPipe } from '../shared/shared-main/common/number-formatter.pipe'
import { SubscribeButtonComponent } from '../shared/shared-user-subscription/subscribe-button.component'
import { MiniatureDisplayOptions, VideoMiniatureComponent } from '../shared/shared-video-miniature/video-miniature.component'
import { VideoPlaylistMiniatureComponent } from '../shared/shared-video-playlist/video-playlist-miniature.component'
import { SearchFiltersComponent } from './search-filters.component'
@Component({
selector: 'my-search',
@ -38,7 +39,8 @@ import { SearchService } from '@app/shared/shared-search/search.service'
SubscribeButtonComponent,
VideoMiniatureComponent,
VideoPlaylistMiniatureComponent,
NumberFormatterPipe
NumberFormatterPipe,
AlertComponent
]
})
export class SearchComponent implements OnInit, OnDestroy {

View File

@ -1,7 +1,7 @@
<div>
<div class="margin-content signup-disabled" *ngIf="signupDisabled">
<div class="alert alert-warning" i18n>Signup is not enabled on this instance.</div>
<my-alert type="warning" i18n>Signup is not enabled on this instance.</my-alert>
</div>
<ng-container *ngIf="!signupDisabled">
@ -114,7 +114,7 @@
<div i18n>PeerTube is creating your account...</div>
</div>
<div *ngIf="signupError" class="alert alert-danger">{{ signupError }}</div>
<my-alert *ngIf="signupError" type="danger">{{ signupError }}</my-alert>
<my-signup-success-before-email
*ngIf="signupSuccess"

View File

@ -1,22 +1,23 @@
import { CdkStep, CdkStepperNext, CdkStepperPrevious } from '@angular/cdk/stepper'
import { NgIf } from '@angular/common'
import { Component, OnInit, ViewChild } from '@angular/core'
import { FormGroup } from '@angular/forms'
import { ActivatedRoute, RouterLink } from '@angular/router'
import { AuthService, ServerService } from '@app/core'
import { HooksService } from '@app/core/plugins/hooks.service'
import { ServerConfig, ServerStats, UserRegister } from '@peertube/peertube-models'
import { SignupService } from '../shared/signup.service'
import { SignupSuccessBeforeEmailComponent } from '../shared/signup-success-before-email.component'
import { LoaderComponent } from '../../shared/shared-main/common/loader.component'
import { RegisterStepChannelComponent } from './steps/register-step-channel.component'
import { RegisterStepUserComponent } from './steps/register-step-user.component'
import { RegisterStepTermsComponent } from './steps/register-step-terms.component'
import { RegisterStepAboutComponent } from './steps/register-step-about.component'
import { SignupStepTitleComponent } from '../shared/signup-step-title.component'
import { CustomStepperComponent } from './custom-stepper.component'
import { SignupLabelComponent } from '../../shared/shared-main/users/signup-label.component'
import { NgIf } from '@angular/common'
import { InstanceAboutAccordionComponent } from '@app/shared/shared-instance/instance-about-accordion.component'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { ServerConfig, ServerStats, UserRegister } from '@peertube/peertube-models'
import { LoaderComponent } from '../../shared/shared-main/common/loader.component'
import { SignupLabelComponent } from '../../shared/shared-main/users/signup-label.component'
import { SignupStepTitleComponent } from '../shared/signup-step-title.component'
import { SignupSuccessBeforeEmailComponent } from '../shared/signup-success-before-email.component'
import { SignupService } from '../shared/signup.service'
import { CustomStepperComponent } from './custom-stepper.component'
import { RegisterStepAboutComponent } from './steps/register-step-about.component'
import { RegisterStepChannelComponent } from './steps/register-step-channel.component'
import { RegisterStepTermsComponent } from './steps/register-step-terms.component'
import { RegisterStepUserComponent } from './steps/register-step-user.component'
@Component({
selector: 'my-register',
@ -38,7 +39,8 @@ import { InstanceAboutAccordionComponent } from '@app/shared/shared-instance/ins
RegisterStepUserComponent,
RegisterStepChannelComponent,
LoaderComponent,
SignupSuccessBeforeEmailComponent
SignupSuccessBeforeEmailComponent,
AlertComponent
]
})
export class RegisterComponent implements OnInit {

View File

@ -1,10 +1,12 @@
<my-instance-banner class="d-block mb-4" rounded="true"></my-instance-banner>
<p class="alert pt-alert-primary text-center" *ngIf="requiresApproval">
<ng-container i18n>Moderators of {{ instanceName }} will have to approve your registration request once you have finished to fill the form.</ng-container>
<my-alert *ngIf="requiresApproval" type="primary" class="text-center">
<p>
<ng-container i18n>Moderators of {{ instanceName }} will have to approve your registration request once you have finished to fill the form.</ng-container>
<ng-container *ngIf="averageResponseTime" i18n>They usually respond within {{ averageResponseTime | myDaysDurationFormatter }}.</ng-container>
</p>
<ng-container *ngIf="averageResponseTime" i18n>They usually respond within {{ averageResponseTime | myDaysDurationFormatter }}.</ng-container>
</p>
</my-alert>
<div class="why">
<h3 i18n>Why creating an account?</h3>

View File

@ -1,16 +1,17 @@
import { NgIf } from '@angular/common'
import { Component, Input } from '@angular/core'
import { ServerService } from '@app/core'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { ServerStats } from '@peertube/peertube-models'
import { DaysDurationFormatterPipe } from '../../../shared/shared-main/date/days-duration-formatter.pipe'
import { NgIf } from '@angular/common'
import { InstanceBannerComponent } from '../../../shared/shared-instance/instance-banner.component'
import { DaysDurationFormatterPipe } from '../../../shared/shared-main/date/days-duration-formatter.pipe'
@Component({
selector: 'my-register-step-about',
templateUrl: './register-step-about.component.html',
styleUrls: [ './register-step-about.component.scss' ],
standalone: true,
imports: [ InstanceBannerComponent, NgIf, DaysDurationFormatterPipe ]
imports: [ InstanceBannerComponent, NgIf, DaysDurationFormatterPipe, AlertComponent ]
})
export class RegisterStepAboutComponent {
@Input() requiresApproval: boolean

View File

@ -1,6 +1,6 @@
<div class="alert pt-alert-primary" i18n *ngIf="videoUploadDisabled">
<my-alert type="primary" i18n *ngIf="videoUploadDisabled">
Video uploads are disabled on this instance, hence your account won't be able to upload videos.
</div>
</my-alert>
<form role="form" [formGroup]="form">
<div class="row">

View File

@ -1,5 +1,4 @@
import { concat, of } from 'rxjs'
import { pairwise } from 'rxjs/operators'
import { NgClass, NgIf } from '@angular/common'
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
import { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'
import { SignupService } from '@app/+signup/shared/signup.service'
@ -11,15 +10,17 @@ import {
} from '@app/shared/form-validators/user-validators'
import { FormReactive } from '@app/shared/shared-forms/form-reactive'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { concat, of } from 'rxjs'
import { pairwise } from 'rxjs/operators'
import { InputTextComponent } from '../../../shared/shared-forms/input-text.component'
import { NgIf, NgClass } from '@angular/common'
@Component({
selector: 'my-register-step-user',
templateUrl: './register-step-user.component.html',
styleUrls: [ './step.component.scss' ],
standalone: true,
imports: [ NgIf, FormsModule, ReactiveFormsModule, NgClass, InputTextComponent ]
imports: [ NgIf, FormsModule, ReactiveFormsModule, NgClass, InputTextComponent, AlertComponent ]
})
export class RegisterStepUserComponent extends FormReactive implements OnInit {
@Input() videoUploadDisabled = false

View File

@ -7,13 +7,13 @@
>
</my-signup-success-after-email>
<div i18n class="alert alert-success" *ngIf="!isRegistrationRequest() && isPendingEmail && success">Email updated.</div>
<my-alert type="success" i18n *ngIf="!isRegistrationRequest() && isPendingEmail && success">Email updated.</my-alert>
<div class="alert alert-danger" *ngIf="failed">
<my-alert type="danger" *ngIf="failed">
<span i18n>An error occurred.</span>
<a i18n class="ms-1 link-orange" routerLink="/verify-account/ask-send-email">
Request a new verification email
</a>
</div>
</my-alert>
</div>

View File

@ -1,15 +1,16 @@
import { NgIf } from '@angular/common'
import { Component, OnInit } from '@angular/core'
import { ActivatedRoute, RouterLink } from '@angular/router'
import { SignupService } from '@app/+signup/shared/signup.service'
import { AuthService, Notifier, ServerService } from '@app/core'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { SignupSuccessAfterEmailComponent } from '../../shared/signup-success-after-email.component'
import { NgIf } from '@angular/common'
@Component({
selector: 'my-verify-account-email',
templateUrl: './verify-account-email.component.html',
standalone: true,
imports: [ NgIf, SignupSuccessAfterEmailComponent, RouterLink ]
imports: [ NgIf, SignupSuccessAfterEmailComponent, RouterLink, AlertComponent ]
})
export class VerifyAccountEmailComponent implements OnInit {

View File

@ -2,7 +2,7 @@
<strong i18n>Email verified!</strong>
</my-signup-step-title>
<div class="alert pt-alert-primary">
<my-alert type="primary">
<ng-container *ngIf="requiresApproval">
<p i18n>Your email has been verified and your account request has been sent!</p>
@ -18,4 +18,4 @@
If you need help using PeerTube, you can have a look at the <a class="link-orange" href="https://docs.joinpeertube.org/use/setup-account" target="_blank" rel="noopener noreferrer">documentation</a>.
</p>
</ng-container>
</div>
</my-alert>

View File

@ -1,5 +1,6 @@
import { Component, Input } from '@angular/core'
import { NgIf } from '@angular/common'
import { Component, Input } from '@angular/core'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { SignupStepTitleComponent } from './signup-step-title.component'
@Component({
@ -7,7 +8,7 @@ import { SignupStepTitleComponent } from './signup-step-title.component'
templateUrl: './signup-success-after-email.component.html',
styleUrls: [ './signup-success.component.scss' ],
standalone: true,
imports: [ SignupStepTitleComponent, NgIf ]
imports: [ SignupStepTitleComponent, NgIf, AlertComponent ]
})
export class SignupSuccessAfterEmailComponent {
@Input() requiresApproval: boolean

View File

@ -9,7 +9,7 @@
</ng-container>
</my-signup-step-title>
<div class="alert pt-alert-primary">
<my-alert type="primary">
<p *ngIf="requiresApproval" i18n>Your account request has been sent!</p>
<p *ngIf="!requiresApproval" i18n>Your account has been created!</p>
@ -32,4 +32,4 @@
If you need help using PeerTube, you can have a look at the <a class="link-orange" href="https://docs.joinpeertube.org/use/setup-account" target="_blank" rel="noopener noreferrer">documentation</a>.
</p>
</ng-container>
</div>
</my-alert>

View File

@ -1,5 +1,6 @@
import { Component, Input } from '@angular/core'
import { NgIf } from '@angular/common'
import { Component, Input } from '@angular/core'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { SignupStepTitleComponent } from './signup-step-title.component'
@Component({
@ -7,7 +8,7 @@ import { SignupStepTitleComponent } from './signup-step-title.component'
templateUrl: './signup-success-before-email.component.html',
styleUrls: [ './signup-success.component.scss' ],
standalone: true,
imports: [ SignupStepTitleComponent, NgIf ]
imports: [ SignupStepTitleComponent, NgIf, AlertComponent ]
})
export class SignupSuccessBeforeEmailComponent {
@Input() requiresApproval: boolean

View File

@ -1,4 +1,5 @@
.alert {
my-alert {
display: block;
font-size: 18px;
max-width: 900px;
text-align: center;

View File

@ -174,9 +174,9 @@
<ng-template ngbNavContent>
<div class="captions">
<div class="alert pt-alert-primary" *ngIf="displayTranscriptionInfo && isTranscriptionEnabled() && !hasCaptions()" i18n>
<my-alert type="primary" *ngIf="displayTranscriptionInfo && isTranscriptionEnabled() && !hasCaptions()" i18n>
A subtitle will be automatically generated from your video.
</div>
</my-alert>
<div class="form-group" *ngFor="let videoCaption of videoCaptions">
@ -246,11 +246,11 @@
<ng-template ngbNavContent>
<div class="row mb-5">
<div class="chapters col-md-12 col-xl-6" formArrayName="chapters">
<div i18n class="alert pt-alert-primary">
<my-alert type="primary" i18n>
Chapters can also be set in the video description.
Check the format <a href="https://docs.joinpeertube.org/use/create-upload-video#chapters" target="_blank">in the PeerTube documentation</a>
</div>
</my-alert>
<ng-container *ngFor="let chapterControl of getChaptersFormArray().controls; let i = index">
<div class="chapter" [formGroupName]="i">
@ -303,9 +303,9 @@
<ng-template ngbNavContent>
<div class="row live-settings">
<div class="col-md-12">
<div class="alert pt-alert-primary">
<my-alert type="primary">
<my-live-documentation-link></my-live-documentation-link>
</div>
</my-alert>
<div *ngIf="liveVideo.rtmpUrl" class="form-group">
<label for="liveVideoRTMPUrl" i18n>Live RTMP Url</label>

View File

@ -32,6 +32,7 @@ import {
} from '@app/shared/form-validators/video-validators'
import { FormReactiveErrors, FormReactiveValidationMessages } from '@app/shared/shared-forms/form-reactive.service'
import { FormValidatorService } from '@app/shared/shared-forms/form-validator.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { InstanceService } from '@app/shared/shared-main/instance/instance.service'
import { VideoCaptionEdit, VideoCaptionWithPathEdit } from '@app/shared/shared-main/video-caption/video-caption-edit.model'
import { VideoChaptersEdit } from '@app/shared/shared-main/video/video-chapters-edit.model'
@ -68,10 +69,11 @@ import { SelectOptionsComponent } from '../../../shared/shared-forms/select/sele
import { SelectTagsComponent } from '../../../shared/shared-forms/select/select-tags.component'
import { TimestampInputComponent } from '../../../shared/shared-forms/timestamp-input.component'
import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.component'
import { PeerTubeTemplateDirective } from '../../../shared/shared-main/common/peertube-template.directive'
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
import { DeleteButtonComponent } from '../../../shared/shared-main/buttons/delete-button.component'
import { EditButtonComponent } from '../../../shared/shared-main/buttons/edit-button.component'
import { HelpComponent } from '../../../shared/shared-main/buttons/help.component'
import { PeerTubeTemplateDirective } from '../../../shared/shared-main/common/peertube-template.directive'
import { EmbedComponent } from '../../../shared/shared-main/video/embed.component'
import { LiveDocumentationLinkComponent } from '../../../shared/shared-video-live/live-documentation-link.component'
import { VideoCaptionAddModalComponent } from './caption/video-caption-add-modal.component'
@ -79,7 +81,6 @@ import { VideoCaptionEditModalContentComponent } from './caption/video-caption-e
import { I18nPrimengCalendarService } from './i18n-primeng-calendar.service'
import { ThumbnailManagerComponent } from './thumbnail-manager/thumbnail-manager.component'
import { VideoEditType } from './video-edit.type'
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
type VideoLanguages = VideoConstant<string> & { group?: string }
type PluginField = {
@ -126,7 +127,8 @@ type PluginField = {
DatePipe,
ThumbnailManagerComponent,
EditButtonComponent,
ButtonComponent
ButtonComponent,
AlertComponent
]
})
export class VideoEditComponent implements OnInit, OnDestroy {

View File

@ -39,15 +39,16 @@
</div>
</div>
<div *ngIf="error" class="alert alert-danger">
<my-alert *ngIf="error" type="danger">
<div i18n>Sorry, but something went wrong</div>
{{ error }}
</div>
<div class="alert pt-alert-primary" i18n *ngIf="isInUpdateForm && getMaxLiveDuration() >= 0">
{{ error }}
</my-alert>
<my-alert type="primary" i18n *ngIf="isInUpdateForm && getMaxLiveDuration() >= 0">
Max live duration is {{ getMaxLiveDuration() | myTimeDurationFormatter }}.
If your live reaches this limit, it will be automatically terminated.
</div>
</my-alert>
<!-- Hidden because we want to load the component -->
<form [hidden]="!isInUpdateForm" novalidate [formGroup]="form">

View File

@ -1,11 +1,18 @@
import { forkJoin } from 'rxjs'
import { NgIf } from '@angular/common'
import { AfterViewInit, Component, EventEmitter, OnInit, Output } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { Router } from '@angular/router'
import { AuthService, CanComponentDeactivate, HooksService, Notifier, ServerService } from '@app/core'
import { scrollToTop } from '@app/helpers'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { VideoCaptionService } from '@app/shared/shared-main/video-caption/video-caption.service'
import { VideoChapterService } from '@app/shared/shared-main/video/video-chapter.service'
import { VideoEdit } from '@app/shared/shared-main/video/video-edit.model'
import { Video } from '@app/shared/shared-main/video/video.model'
import { VideoService } from '@app/shared/shared-main/video/video.service'
import { LiveVideoService } from '@app/shared/shared-video-live/live-video.service'
import { LoadingBarService } from '@ngx-loading-bar/core'
import { logger } from '@root-helpers/logger'
import {
LiveVideo,
LiveVideoCreate,
@ -15,21 +22,15 @@ import {
ServerErrorCode,
VideoPrivacy
} from '@peertube/peertube-models'
import { VideoSend } from './video-send'
import { TimeDurationFormatterPipe } from '../../../shared/shared-main/date/time-duration-formatter.pipe'
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
import { VideoEditComponent } from '../shared/video-edit.component'
import { SelectOptionsComponent } from '../../../shared/shared-forms/select/select-options.component'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { logger } from '@root-helpers/logger'
import { forkJoin } from 'rxjs'
import { SelectChannelComponent } from '../../../shared/shared-forms/select/select-channel.component'
import { SelectOptionsComponent } from '../../../shared/shared-forms/select/select-options.component'
import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.component'
import { NgIf } from '@angular/common'
import { VideoCaptionService } from '@app/shared/shared-main/video-caption/video-caption.service'
import { VideoChapterService } from '@app/shared/shared-main/video/video-chapter.service'
import { VideoEdit } from '@app/shared/shared-main/video/video-edit.model'
import { Video } from '@app/shared/shared-main/video/video.model'
import { VideoService } from '@app/shared/shared-main/video/video.service'
import { LiveVideoService } from '@app/shared/shared-video-live/live-video.service'
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
import { TimeDurationFormatterPipe } from '../../../shared/shared-main/date/time-duration-formatter.pipe'
import { VideoEditComponent } from '../shared/video-edit.component'
import { VideoSend } from './video-send'
@Component({
selector: 'my-video-go-live',
@ -49,7 +50,8 @@ import { LiveVideoService } from '@app/shared/shared-video-live/live-video.servi
ReactiveFormsModule,
VideoEditComponent,
ButtonComponent,
TimeDurationFormatterPipe
TimeDurationFormatterPipe,
AlertComponent
]
})
export class VideoGoLiveComponent extends VideoSend implements OnInit, AfterViewInit, CanComponentDeactivate {

View File

@ -47,14 +47,15 @@
</div>
</div>
<div *ngIf="error" class="alert alert-danger">
<my-alert *ngIf="error" type="danger">
<div i18n>Sorry, but something went wrong</div>
{{ error }}
</div>
<div *ngIf="hasImportedVideo && !error" class="alert pt-alert-primary" i18n>
{{ error }}
</my-alert>
<my-alert type="primary" *ngIf="hasImportedVideo && !error" i18n>
Congratulations, the video will be imported with BitTorrent! You can already add information about this video.
</div>
</my-alert>
<!-- Hidden because we want to load the component -->
<form [hidden]="!hasImportedVideo" novalidate [formGroup]="form">

View File

@ -1,30 +1,31 @@
import { switchMap } from 'rxjs'
import { NgIf } from '@angular/common'
import { AfterViewInit, Component, ElementRef, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { Router } from '@angular/router'
import { AuthService, CanComponentDeactivate, HooksService, Notifier, ServerService } from '@app/core'
import { scrollToTop } from '@app/helpers'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { LoadingBarService } from '@ngx-loading-bar/core'
import { logger } from '@root-helpers/logger'
import { PeerTubeProblemDocument, ServerErrorCode, VideoUpdate } from '@peertube/peertube-models'
import { hydrateFormFromVideo } from '../shared/video-edit-utils'
import { VideoSend } from './video-send'
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
import { VideoEditComponent } from '../shared/video-edit.component'
import { SelectOptionsComponent } from '../../../shared/shared-forms/select/select-options.component'
import { SelectChannelComponent } from '../../../shared/shared-forms/select/select-channel.component'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { PeerTubeTemplateDirective } from '../../../shared/shared-main/common/peertube-template.directive'
import { HelpComponent } from '../../../shared/shared-main/buttons/help.component'
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'
import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.component'
import { DragDropDirective } from './drag-drop.directive'
import { NgIf } from '@angular/common'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { VideoCaptionService } from '@app/shared/shared-main/video-caption/video-caption.service'
import { VideoChapterService } from '@app/shared/shared-main/video/video-chapter.service'
import { VideoEdit } from '@app/shared/shared-main/video/video-edit.model'
import { VideoImportService } from '@app/shared/shared-main/video/video-import.service'
import { VideoService } from '@app/shared/shared-main/video/video.service'
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'
import { LoadingBarService } from '@ngx-loading-bar/core'
import { PeerTubeProblemDocument, ServerErrorCode, VideoUpdate } from '@peertube/peertube-models'
import { logger } from '@root-helpers/logger'
import { switchMap } from 'rxjs'
import { SelectChannelComponent } from '../../../shared/shared-forms/select/select-channel.component'
import { SelectOptionsComponent } from '../../../shared/shared-forms/select/select-options.component'
import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.component'
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
import { HelpComponent } from '../../../shared/shared-main/buttons/help.component'
import { PeerTubeTemplateDirective } from '../../../shared/shared-main/common/peertube-template.directive'
import { hydrateFormFromVideo } from '../shared/video-edit-utils'
import { VideoEditComponent } from '../shared/video-edit.component'
import { DragDropDirective } from './drag-drop.directive'
import { VideoSend } from './video-send'
@Component({
selector: 'my-video-import-torrent',
@ -47,7 +48,8 @@ import { VideoService } from '@app/shared/shared-main/video/video.service'
SelectOptionsComponent,
ReactiveFormsModule,
VideoEditComponent,
ButtonComponent
ButtonComponent,
AlertComponent
]
})
export class VideoImportTorrentComponent extends VideoSend implements OnInit, AfterViewInit, CanComponentDeactivate {

View File

@ -44,14 +44,15 @@
</div>
<div *ngIf="error" class="alert alert-danger">
<my-alert *ngIf="error" type="danger">
<div i18n>Sorry, but something went wrong</div>
{{ error }}
</div>
<div *ngIf="!error && hasImportedVideo" class="alert pt-alert-primary" i18n>
{{ error }}
</my-alert>
<my-alert type="primary" *ngIf="!error && hasImportedVideo" i18n>
Congratulations, the video behind {{ targetUrl }} will be imported! You can already add information about this video.
</div>
</my-alert>
<!-- Hidden because we want to load the component -->
<form [hidden]="!hasImportedVideo" novalidate [formGroup]="form">

View File

@ -1,29 +1,30 @@
import { forkJoin } from 'rxjs'
import { map, switchMap } from 'rxjs/operators'
import { NgIf } from '@angular/common'
import { AfterViewInit, Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { Router, RouterLink } from '@angular/router'
import { AuthService, CanComponentDeactivate, HooksService, Notifier, ServerService } from '@app/core'
import { scrollToTop } from '@app/helpers'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { LoadingBarService } from '@ngx-loading-bar/core'
import { logger } from '@root-helpers/logger'
import { VideoUpdate } from '@peertube/peertube-models'
import { hydrateFormFromVideo } from '../shared/video-edit-utils'
import { VideoSend } from './video-send'
import { VideoEditComponent } from '../shared/video-edit.component'
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
import { SelectOptionsComponent } from '../../../shared/shared-forms/select/select-options.component'
import { SelectChannelComponent } from '../../../shared/shared-forms/select/select-channel.component'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { PeerTubeTemplateDirective } from '../../../shared/shared-main/common/peertube-template.directive'
import { HelpComponent } from '../../../shared/shared-main/buttons/help.component'
import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.component'
import { NgIf } from '@angular/common'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { VideoCaptionService } from '@app/shared/shared-main/video-caption/video-caption.service'
import { VideoChapterService } from '@app/shared/shared-main/video/video-chapter.service'
import { VideoEdit } from '@app/shared/shared-main/video/video-edit.model'
import { VideoImportService } from '@app/shared/shared-main/video/video-import.service'
import { VideoService } from '@app/shared/shared-main/video/video.service'
import { LoadingBarService } from '@ngx-loading-bar/core'
import { VideoUpdate } from '@peertube/peertube-models'
import { logger } from '@root-helpers/logger'
import { forkJoin } from 'rxjs'
import { map, switchMap } from 'rxjs/operators'
import { SelectChannelComponent } from '../../../shared/shared-forms/select/select-channel.component'
import { SelectOptionsComponent } from '../../../shared/shared-forms/select/select-options.component'
import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.component'
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
import { HelpComponent } from '../../../shared/shared-main/buttons/help.component'
import { PeerTubeTemplateDirective } from '../../../shared/shared-main/common/peertube-template.directive'
import { hydrateFormFromVideo } from '../shared/video-edit-utils'
import { VideoEditComponent } from '../shared/video-edit.component'
import { VideoSend } from './video-send'
@Component({
selector: 'my-video-import-url',
@ -44,7 +45,8 @@ import { VideoService } from '@app/shared/shared-main/video/video.service'
SelectOptionsComponent,
ReactiveFormsModule,
VideoEditComponent,
ButtonComponent
ButtonComponent,
AlertComponent
]
})
export class VideoImportUrlComponent extends VideoSend implements OnInit, AfterViewInit, CanComponentDeactivate {

View File

@ -58,9 +58,9 @@
>
</my-upload-progress>
<div *ngIf="videoUploaded && !error" class="alert pt-alert-primary" i18n>
<my-alert *ngIf="videoUploaded && !error" type="primary" i18n>
Congratulations! Your video is now available in your private library.
</div>
</my-alert>
<!-- Hidden because we want to load the component -->
<form [hidden]="!isUploadingVideo" novalidate [formGroup]="form" class="mb-3">

View File

@ -1,33 +1,34 @@
import { truncate } from 'lodash-es'
import { UploadState, UploadxService } from 'ngx-uploadx'
import { Subscription } from 'rxjs'
import { NgIf } from '@angular/common'
import { HttpErrorResponse } from '@angular/common/http'
import { AfterViewInit, Component, ElementRef, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { ActivatedRoute, Router } from '@angular/router'
import { AuthService, CanComponentDeactivate, HooksService, MetaService, Notifier, ServerService, UserService } from '@app/core'
import { buildHTTPErrorResponse, genericUploadErrorHandler, scrollToTop } from '@app/helpers'
import { LoadingBarService } from '@ngx-loading-bar/core'
import { logger } from '@root-helpers/logger'
import { HttpStatusCode, VideoCreateResult } from '@peertube/peertube-models'
import { VideoUploadService } from '../shared/video-upload.service'
import { VideoSend } from './video-send'
import { VideoEditComponent } from '../shared/video-edit.component'
import { UploadProgressComponent } from '../../../shared/standalone-upload/upload-progress.component'
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
import { PreviewUploadComponent } from '../../../shared/shared-forms/preview-upload.component'
import { SelectOptionsComponent } from '../../../shared/shared-forms/select/select-options.component'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { SelectChannelComponent } from '../../../shared/shared-forms/select/select-channel.component'
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'
import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.component'
import { DragDropDirective } from './drag-drop.directive'
import { NgIf } from '@angular/common'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { VideoCaptionService } from '@app/shared/shared-main/video-caption/video-caption.service'
import { VideoChapterService } from '@app/shared/shared-main/video/video-chapter.service'
import { VideoEdit } from '@app/shared/shared-main/video/video-edit.model'
import { Video } from '@app/shared/shared-main/video/video.model'
import { VideoService } from '@app/shared/shared-main/video/video.service'
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap'
import { LoadingBarService } from '@ngx-loading-bar/core'
import { HttpStatusCode, VideoCreateResult } from '@peertube/peertube-models'
import { logger } from '@root-helpers/logger'
import { truncate } from 'lodash-es'
import { UploadState, UploadxService } from 'ngx-uploadx'
import { Subscription } from 'rxjs'
import { PreviewUploadComponent } from '../../../shared/shared-forms/preview-upload.component'
import { SelectChannelComponent } from '../../../shared/shared-forms/select/select-channel.component'
import { SelectOptionsComponent } from '../../../shared/shared-forms/select/select-options.component'
import { GlobalIconComponent } from '../../../shared/shared-icons/global-icon.component'
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
import { UploadProgressComponent } from '../../../shared/standalone-upload/upload-progress.component'
import { VideoEditComponent } from '../shared/video-edit.component'
import { VideoUploadService } from '../shared/video-upload.service'
import { DragDropDirective } from './drag-drop.directive'
import { VideoSend } from './video-send'
@Component({
selector: 'my-video-upload',
@ -50,7 +51,8 @@ import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.serv
ButtonComponent,
UploadProgressComponent,
ReactiveFormsModule,
VideoEditComponent
VideoEditComponent,
AlertComponent
]
})
export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy, AfterViewInit, CanComponentDeactivate {

View File

@ -1,13 +1,16 @@
<ng-template #AlertButtons>
<a i18n routerLink="/about/instance" *ngIf="!isContactFormEnabled" class="about-link">Read instance rules for help</a>
<a i18n routerLink="/about/contact" *ngIf="isContactFormEnabled" class="contact-link">Contact us</a>
@if (isContactFormEnabled) {
<a i18n routerLink="/about/contact" class="peertube-button-link orange-button mt-2">Contact us</a>
} @else {
<a i18n routerLink="/about/instance" class="peertube-button-link orange-button mt-2">Read instance rules for help</a>
}
</ng-template>
<ng-container *ngIf="user.isUploadDisabled()">
<div class="upload-message upload-disabled alert alert-warning">
<my-alert class="upload-message upload-disabled" type="warning">
<div>{{ uploadMessages?.noQuota }}</div>
<ng-template [ngTemplateOutlet]="AlertButtons"></ng-template>
</div>
</my-alert>
<div class="upload-image">
<img src="/client/assets/images/mascot/defeated.svg" alt="defeated mascot">
@ -15,26 +18,28 @@
</ng-container>
<ng-container *ngIf="!user.isUploadDisabled()">
<div *ngIf="user.isAutoBlocked(serverConfig)" class="upload-message auto-blocked alert alert-warning">
<my-alert rounded="false" *ngIf="user.isAutoBlocked(serverConfig)" class="upload-message auto-blocked" type="warning">
<div>{{ uploadMessages?.autoBlock }}</div>
<ng-template [ngTemplateOutlet]="AlertButtons" *ngIf="!hasNoQuotaLeft && !hasNoQuotaLeftDaily"></ng-template>
</div>
</my-alert>
<div *ngIf="hasNoQuotaLeftDaily" class="upload-message quota-daily-left alert alert-warning">
<my-alert rounded="false" *ngIf="hasNoQuotaLeftDaily" class="upload-message quota-daily-left" type="warning">
<div>{{ uploadMessages?.quotaLeftDaily }}</div>
<ng-template [ngTemplateOutlet]="AlertButtons" *ngIf="!hasNoQuotaLeft"></ng-template>
</div>
</my-alert>
<div *ngIf="hasNoQuotaLeft" class="upload-message quota-left alert alert-warning">
<my-alert rounded="false" *ngIf="hasNoQuotaLeft" class="upload-message quota-left" type="warning">
<div>{{ uploadMessages?.quotaLeft }}</div>
<ng-template [ngTemplateOutlet]="AlertButtons"></ng-template>
</div>
</my-alert>
<my-alert rounded="false" *ngIf="isRootUser()" class="upload-message root-user root-user root-user" type="warning">
<ng-container i18n>We recommend you to not use the <strong>root</strong> user to publish your videos, since it's the super-admin account of your instance.</ng-container>
<div *ngIf="isRootUser()" class="upload-message root-user alert alert-warning" i18n>
We recommend you to not use the <strong>root</strong> user to publish your videos, since it's the super-admin account of your instance.
<br />
Instead, <a class="text-decoration-underline alert-link" routerLink="/admin/users">create a dedicated account</a> to upload your videos.
</div>
<ng-container i18n>Instead, <a class="text-decoration-underline alert-link" routerLink="/admin/users">create a dedicated account</a> to upload your videos.</ng-container>
</my-alert>
</ng-container>
<div *ngIf="!user.isUploadDisabled()" class="margin-content">

View File

@ -8,23 +8,14 @@ $border-color: #EAEAEA;
$nav-link-height: 40px;
.upload-message {
display: block;
width: 100%;
text-align: center;
margin-bottom: 0;
border-radius: 0;
&:last-child {
margin-bottom: 1rem;
}
.about-link,
.contact-link {
height: fit-content;
margin-top: 10px;
@include peertube-button-link;
@include orange-button;
}
}
.upload-image {

View File

@ -1,3 +1,4 @@
import { NgClass, NgIf, NgTemplateOutlet } from '@angular/common'
import { Component, HostListener, OnInit, ViewChild } from '@angular/core'
import { ActivatedRoute, Router, RouterLink } from '@angular/router'
import {
@ -8,16 +9,16 @@ import {
ServerService,
UserService
} from '@app/core'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { NgbNav, NgbNavContent, NgbNavItem, NgbNavLink, NgbNavLinkBase, NgbNavOutlet } from '@ng-bootstrap/ng-bootstrap'
import { HTMLServerConfig } from '@peertube/peertube-models'
import { ChannelsSetupMessageComponent } from '../../shared/shared-main/channel/channels-setup-message.component'
import { UserQuotaComponent } from '../../shared/shared-main/users/user-quota.component'
import { VideoEditType } from './shared/video-edit.type'
import { VideoGoLiveComponent } from './video-add-components/video-go-live.component'
import { VideoImportTorrentComponent } from './video-add-components/video-import-torrent.component'
import { VideoImportUrlComponent } from './video-add-components/video-import-url.component'
import { VideoUploadComponent } from './video-add-components/video-upload.component'
import { NgbNav, NgbNavItem, NgbNavLink, NgbNavLinkBase, NgbNavContent, NgbNavOutlet } from '@ng-bootstrap/ng-bootstrap'
import { ChannelsSetupMessageComponent } from '../../shared/shared-main/channel/channels-setup-message.component'
import { UserQuotaComponent } from '../../shared/shared-main/users/user-quota.component'
import { NgIf, NgTemplateOutlet, NgClass } from '@angular/common'
@Component({
selector: 'my-videos-add',
@ -40,7 +41,8 @@ import { NgIf, NgTemplateOutlet, NgClass } from '@angular/common'
VideoImportUrlComponent,
VideoImportTorrentComponent,
VideoGoLiveComponent,
NgbNavOutlet
NgbNavOutlet,
AlertComponent
]
})
export class VideoAddComponent implements OnInit, CanComponentDeactivate {

View File

@ -1,28 +1,28 @@
<div i18n class="alert pt-alert-primary" *ngIf="hasVideoScheduledPublication()">
<my-alert rounded="false" type="primary" i18n *ngIf="hasVideoScheduledPublication()">
This video will be published on {{ video.scheduledUpdate.updateAt | date: 'full' }}.
</div>
</my-alert>
<div i18n class="alert pt-alert-primary" *ngIf="isWaitingForLive()">
<my-alert rounded="false" type="primary" i18n *ngIf="isWaitingForLive()">
This live is not currently streaming.
</div>
</my-alert>
<div i18n class="alert pt-alert-primary" *ngIf="isLiveEnded()">
<my-alert rounded="false" type="primary" i18n *ngIf="isLiveEnded()">
This live has ended.
</div>
</my-alert>
<div class="alert alert-warning" *ngIf="getAlertWarning()">
<my-alert rounded="false" type="warning" *ngIf="getAlertWarning()">
{{ getAlertWarning() }}
</div>
</my-alert>
<div i18n class="alert alert-warning" *ngIf="noPlaylistVideoFound">
<my-alert rounded="false" i18n type="warning" *ngIf="noPlaylistVideoFound">
There are no videos available in this playlist.
</div>
</my-alert>
<div class="alert alert-danger" *ngIf="video?.blacklisted">
<my-alert rounded="false" type="danger" *ngIf="video?.blacklisted">
<div class="blocked-label" i18n>This video is blocked.</div>
{{ video.blacklistedReason }}
</div>
</my-alert>
<div i18n class="alert alert-warning" *ngIf="video?.canAccessPasswordProtectedVideoWithoutPassword(user)">
<my-alert rounded="false" i18n type="warning" *ngIf="video?.canAccessPasswordProtectedVideoWithoutPassword(user)">
This video is password protected.
</div>
</my-alert>

View File

@ -1,7 +0,0 @@
@use '_variables' as *;
@use '_mixins' as *;
.alert {
text-align: center;
border-radius: 0;
}

View File

@ -1,15 +1,16 @@
import { DatePipe, NgIf } from '@angular/common'
import { Component, Input } from '@angular/core'
import { AuthUser } from '@app/core'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { VideoDetails } from '@app/shared/shared-main/video/video-details.model'
import { VideoPrivacy, VideoState } from '@peertube/peertube-models'
import { NgIf, DatePipe } from '@angular/common'
@Component({
selector: 'my-video-alert',
templateUrl: './video-alert.component.html',
styleUrls: [ './video-alert.component.scss' ],
standalone: true,
imports: [ NgIf, DatePipe ]
styles: `my-alert { text-align: center }`,
imports: [ NgIf, DatePipe, AlertComponent ]
})
export class VideoAlertComponent {
@Input() user: AuthUser

View File

@ -7,7 +7,7 @@
</div>
<div class="modal-body">
<div i18n class="alert pt-alert-primary">These settings apply only to your session on this instance.</div>
<my-alert i18n type="primary">These settings apply only to your session on this instance.</my-alert>
<h5 i18n class="mt-4 mb-2">Videos</h5>

View File

@ -1,20 +1,21 @@
import { ReplaySubject, Subscription } from 'rxjs'
import { filter } from 'rxjs/operators'
import { CommonModule } from '@angular/common'
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { AuthService, AuthStatus, LocalStorageService, User, UserService } from '@app/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
import { CommonModule } from '@angular/common'
import { GlobalIconComponent } from '@app/shared/shared-icons/global-icon.component'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import { UserInterfaceSettingsComponent } from '@app/shared/shared-user-settings/user-interface-settings.component'
import { UserVideoSettingsComponent } from '@app/shared/shared-user-settings/user-video-settings.component'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
import { ReplaySubject, Subscription } from 'rxjs'
import { filter } from 'rxjs/operators'
@Component({
selector: 'my-quick-settings',
templateUrl: './quick-settings-modal.component.html',
standalone: true,
imports: [ CommonModule, GlobalIconComponent, UserVideoSettingsComponent, UserInterfaceSettingsComponent ]
imports: [ CommonModule, GlobalIconComponent, UserVideoSettingsComponent, UserInterfaceSettingsComponent, AlertComponent ]
})
export class QuickSettingsModalComponent implements OnInit, OnDestroy {
private static readonly QUERY_MODAL_NAME = 'quick-settings'

View File

@ -1,7 +1,7 @@
<div *ngIf="hasChannelNotConfigured()" class="alert pt-alert-primary">
<my-alert *ngIf="hasChannelNotConfigured()" type="primary" class="text-center">
<my-global-icon iconName="tip"></my-global-icon>
<div i18n>Some of your channels are not fully set up. Make them welcoming and explicit about what you publish by adding a <strong>banner</strong>, an <strong>avatar</strong> and a <strong>description</strong>.</div>
<a *ngIf="!hideLink" class="peertube-button-link grey-button mt-2" routerLink="/my-library/video-channels" i18n>Set up my channels</a>
</div>
</my-alert>

View File

@ -1,10 +1,6 @@
@use '_variables' as *;
@use '_mixins' as *;
.pt-alert-primary {
text-align: center;
}
my-global-icon {
width: 32px;
display: inline-block;

View File

@ -1,8 +1,9 @@
import { Component, Input, OnInit } from '@angular/core'
import { AuthService, User } from '@app/core'
import { RouterLink } from '@angular/router'
import { GlobalIconComponent } from '../../shared-icons/global-icon.component'
import { NgIf } from '@angular/common'
import { Component, Input, OnInit } from '@angular/core'
import { RouterLink } from '@angular/router'
import { AuthService, User } from '@app/core'
import { GlobalIconComponent } from '../../shared-icons/global-icon.component'
import { AlertComponent } from '../common/alert.component'
import { VideoChannel } from './video-channel.model'
@Component({
@ -10,7 +11,7 @@ import { VideoChannel } from './video-channel.model'
templateUrl: './channels-setup-message.component.html',
styleUrls: [ './channels-setup-message.component.scss' ],
standalone: true,
imports: [ NgIf, GlobalIconComponent, RouterLink ]
imports: [ NgIf, GlobalIconComponent, RouterLink, AlertComponent ]
})
export class ChannelsSetupMessageComponent implements OnInit {
@Input() hideLink = false

View File

@ -0,0 +1,3 @@
<div [ngClass]="builtClasses" role="alert">
<ng-content></ng-content>
</div>

View File

@ -0,0 +1,41 @@
import { NgClass, NgIf, NgTemplateOutlet } from '@angular/common'
import { booleanAttribute, Component, Input, OnChanges, OnInit } from '@angular/core'
import { RouterLink } from '@angular/router'
export type AlertType = 'success' | 'info' | 'warning' | 'danger' | 'primary'
@Component({
selector: 'my-alert',
styleUrls: [ './alert.component.scss' ],
templateUrl: './alert.component.html',
standalone: true,
imports: [ NgIf, RouterLink, NgClass, NgTemplateOutlet ]
})
export class AlertComponent implements OnInit, OnChanges {
@Input({ required: true }) type: AlertType
@Input({ transform: booleanAttribute }) rounded = true
builtClasses = ''
ngOnInit () {
this.buildClasses()
}
ngOnChanges () {
this.buildClasses()
}
private buildClasses () {
this.builtClasses = 'alert'
if (this.type === 'primary') {
this.builtClasses += ' pt-alert-primary'
} else {
this.builtClasses += ' alert-' + this.type
}
if (this.rounded !== true) {
this.builtClasses += ' rounded-0'
}
}
}

View File

@ -13,13 +13,13 @@
<div class="playlist" *ngIf="playlist">
<h5 *ngIf="video" i18n class="text-center mb-4">Share the playlist</h5>
<div *ngIf="isPrivatePlaylist()" class="alert-private alert alert-warning">
<my-alert *ngIf="isPrivatePlaylist()" class="alert-private" type="warning">
<div i18n>This playlist is private so you won't be able to share it with external users</div>
<a i18n class="peertube-button-link orange-button" [routerLink]="[ '/my-library/video-playlists/update', playlist.shortUUID ]" target="_blank" rel="noopener noreferrer">
Update playlist privacy
</a>
</div>
</my-alert>
<div ngbNav #nav="ngbNav" class="nav-tabs" [(activeId)]="activePlaylistId">
@ -57,9 +57,9 @@
[withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"
></my-input-text>
<div i18n *ngIf="notSecure()" class="alert alert-warning">
<my-alert i18n *ngIf="notSecure()" type="warning">
The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites).
</div>
</my-alert>
<div class="embed" [innerHTML]="playlistEmbedSafeHTML"></div>
</div>
@ -103,17 +103,17 @@
<div class="video" *ngIf="video">
<h5 *ngIf="playlist" i18n class="text-center mb-4">Share the video</h5>
<div *ngIf="isPrivateVideo()" class="alert-private alert alert-warning">
<my-alert *ngIf="isPrivateVideo()" class="alert-private" type="warning">
<div i18n>This video is private so you won't be able to share it with external users</div>
<a i18n class="peertube-button-link orange-button" [routerLink]="[ '/videos/', 'update', video.shortUUID ]" target="_blank" rel="noopener noreferrer">
Update video privacy
</a>
</div>
</my-alert>
<div i18n *ngIf="isPasswordProtectedVideo()" class="alert-private alert alert-warning">
<my-alert i18n *ngIf="isPasswordProtectedVideo()" class="alert-private" type="warning">
This video is password protected, please note that recipients will require the corresponding password to access the content.
</div>
</my-alert>
<div ngbNav #nav="ngbNav" class="nav-tabs" [(activeId)]="activeVideoId">
@ -151,9 +151,9 @@
[withToggle]="false" [withCopy]="true" [show]="true" [readonly]="true"
></my-input-text>
<div i18n *ngIf="notSecure()" class="alert alert-warning">
<my-alert i18n *ngIf="notSecure()" type="warning">
The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites).
</div>
</my-alert>
<div class="embed" [innerHTML]="videoEmbedSafeHTML"></div>
</div>

View File

@ -1,29 +1,30 @@
import { NgClass, NgFor, NgIf } from '@angular/common'
import { Component, ElementRef, Input, ViewChild } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
import { RouterLink } from '@angular/router'
import { HooksService, ServerService } from '@app/core'
import { VideoDetails } from '@app/shared/shared-main/video/video-details.model'
import {
NgbCollapse,
NgbModal,
NgbNav,
NgbNavContent,
NgbNavItem,
NgbNavLink,
NgbNavLinkBase,
NgbNavContent,
NgbNavOutlet,
NgbCollapse
NgbNavOutlet
} from '@ng-bootstrap/ng-bootstrap'
import { buildVideoOrPlaylistEmbed } from '@root-helpers/video'
import { buildPlaylistLink, buildVideoLink, decoratePlaylistLink, decorateVideoLink } from '@peertube/peertube-core-utils'
import { VideoCaption, VideoPlaylistPrivacy, VideoPrivacy } from '@peertube/peertube-models'
import { TimestampInputComponent } from '../shared-forms/timestamp-input.component'
import { PluginPlaceholderComponent } from '../shared-main/plugins/plugin-placeholder.component'
import { FormsModule } from '@angular/forms'
import { PeertubeCheckboxComponent } from '../shared-forms/peertube-checkbox.component'
import { buildVideoOrPlaylistEmbed } from '@root-helpers/video'
import { QRCodeModule } from 'angularx-qrcode'
import { InputTextComponent } from '../shared-forms/input-text.component'
import { RouterLink } from '@angular/router'
import { NgIf, NgClass, NgFor } from '@angular/common'
import { PeertubeCheckboxComponent } from '../shared-forms/peertube-checkbox.component'
import { TimestampInputComponent } from '../shared-forms/timestamp-input.component'
import { GlobalIconComponent } from '../shared-icons/global-icon.component'
import { AlertComponent } from '../shared-main/common/alert.component'
import { PluginPlaceholderComponent } from '../shared-main/plugins/plugin-placeholder.component'
import { VideoPlaylist } from '../shared-video-playlist/video-playlist.model'
type Customizations = {
@ -77,7 +78,8 @@ type TabId = 'url' | 'qrcode' | 'embed'
TimestampInputComponent,
NgClass,
NgFor,
NgbCollapse
NgbCollapse,
AlertComponent
]
})
export class VideoShareComponent {

View File

@ -13,9 +13,9 @@
<div class="pt-badge badge-blue" *ngIf="live.saveReplay" i18n>Replay will be saved</div>
</div>
<div class="alert pt-alert-primary">
<my-alert type="primary">
<my-live-documentation-link></my-live-documentation-link>
</div>
</my-alert>
<div *ngIf="live.rtmpUrl" class="form-group">
<label for="liveVideoRTMPUrl" i18n>Live RTMP Url</label>

View File

@ -9,7 +9,8 @@ p-autocomplete {
margin: 20px 0;
}
.pt-alert-primary {
my-alert {
display: block;
margin: 1rem 0;
}

View File

@ -1,14 +1,15 @@
import { DatePipe, NgFor, NgIf } from '@angular/common'
import { Component, ElementRef, ViewChild } from '@angular/core'
import { RouterLink } from '@angular/router'
import { Video } from '@app/shared/shared-main/video/video.model'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { LiveVideo, LiveVideoError, LiveVideoErrorType, LiveVideoSession } from '@peertube/peertube-models'
import { LiveVideoService } from './live-video.service'
import { EditButtonComponent } from '../shared-main/buttons/edit-button.component'
import { RouterLink } from '@angular/router'
import { InputTextComponent } from '../shared-forms/input-text.component'
import { LiveDocumentationLinkComponent } from './live-documentation-link.component'
import { NgIf, NgFor, DatePipe } from '@angular/common'
import { GlobalIconComponent } from '../shared-icons/global-icon.component'
import { EditButtonComponent } from '../shared-main/buttons/edit-button.component'
import { AlertComponent } from '../shared-main/common/alert.component'
import { LiveDocumentationLinkComponent } from './live-documentation-link.component'
import { LiveVideoService } from './live-video.service'
@Component({
selector: 'my-live-stream-information',
@ -23,7 +24,8 @@ import { GlobalIconComponent } from '../shared-icons/global-icon.component'
NgFor,
RouterLink,
EditButtonComponent,
DatePipe
DatePipe,
AlertComponent
],
providers: [ LiveVideoService ]
})

View File

@ -1,6 +1,6 @@
<div class="alert alert-warning" *ngIf="isConfidentialVideo()" i18n>
<my-alert type="warning" *ngIf="isConfidentialVideo()" i18n>
The following link contains a private token and should not be shared with anyone.
</div>
</my-alert>
<div ngbNav #resolutionNav="ngbNav" class="nav-tabs" [activeId]="activeResolutionId" (activeIdChange)="onResolutionIdChange($event)">

View File

@ -1,6 +1,7 @@
import { KeyValuePipe, NgClass, NgFor, NgIf, NgTemplateOutlet } from '@angular/common'
import { Component, EventEmitter, Inject, Input, LOCALE_ID, OnInit, Output } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { AlertComponent } from '@app/shared/shared-main/common/alert.component'
import {
NgbCollapse,
NgbNav,
@ -48,7 +49,8 @@ type FileMetadata = { [key: string]: { label: string, value: string | number } }
KeyValuePipe,
NgbTooltip,
NgTemplateOutlet,
NgClass
NgClass,
AlertComponent
]
})
export class VideoFilesDownloadComponent implements OnInit {

View File

@ -23,7 +23,7 @@
<input type="button" class="peertube-button grey-button ms-1" i18n-value="Cancel ongoing upload" value="Cancel" (click)="cancel.emit()" />
</div>
<div *ngIf="error && !enableRetryAfterError" class="alert alert-danger">
<my-alert *ngIf="error && !enableRetryAfterError" type="danger">
<div i18n>Sorry, but something went wrong</div>
{{ error }}
</div>
</my-alert>

View File

@ -1,12 +1,13 @@
import { CommonModule } from '@angular/common'
import { Component, EventEmitter, Input, Output } from '@angular/core'
import { AlertComponent } from '../shared-main/common/alert.component'
import { ProgressBarComponent } from '../shared-main/common/progress-bar.component'
@Component({
selector: 'my-upload-progress',
templateUrl: './upload-progress.component.html',
styleUrls: [ './upload-progress.component.scss' ],
imports: [ CommonModule, ProgressBarComponent ],
imports: [ CommonModule, ProgressBarComponent, AlertComponent ],
standalone: true
})
export class UploadProgressComponent {

View File

@ -130,6 +130,8 @@ async function getUser (usernameOrEmail?: string, password?: string, bypassLogin
checkUserValidityOrThrow(user)
if (CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION && user.emailVerified === false) {
// Keep this message sync with the client
// TODO: use custom server code
throw new AccessDeniedError('User email is not verified.')
}