Simplify two columns layout

pull/6266/head
Chocobozzz 2024-03-01 14:42:10 +01:00
parent c8d1f0d9c5
commit 275ba643eb
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
28 changed files with 391 additions and 431 deletions

View File

@ -10,7 +10,7 @@ export class AdminConfigPage {
}
await go('/admin/config/edit-custom#' + tab)
await $('.section-left-column-title=' + waitTitles[tab]).waitForDisplayed()
await $('h2=' + waitTitles[tab]).waitForDisplayed()
}
async updateNSFWSetting (newValue: 'do_not_list' | 'blur' | 'display') {

View File

@ -1,15 +1,15 @@
<ng-container [formGroup]="form">
<div class="row mt-5"> <!-- cache grid -->
<div class="pt-two-cols mt-5"> <!-- cache grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">CACHE</h2>
<div class="title-col">
<h2 i18n>CACHE</h2>
<div i18n class="inner-form-description">
Some files are not federated, and fetched when necessary. Define their caching policies.
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="cache">
<div class="form-group" formGroupName="previews">
<label i18n for="cachePreviewsSize">Number of previews to keep in cache</label>
@ -71,16 +71,16 @@
</div>
</div>
<div class="row mt-4"> <!-- cache grid -->
<div class="col-12 col-lg-4 col-xl-3">
<div class="pt-two-cols mt-4"> <!-- cache grid -->
<div class="title-col">
<div class="anchor" id="customizations"></div> <!-- customizations anchor -->
<h2 i18n class="section-left-column-title">CUSTOMIZATIONS</h2>
<h2 i18n>CUSTOMIZATIONS</h2>
<div i18n class="inner-form-description">
Slight modifications to your PeerTube instance for when creating a plugin or theme is overkill.
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="instance">
<ng-container formGroupName="customizations">
<div class="form-group">

View File

@ -1,13 +1,14 @@
<ng-container [formGroup]="form">
<div class="row mt-5"> <!-- appearance grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">APPEARANCE</h2>
<div class="pt-two-cols mt-5"> <!-- appearance grid -->
<div class="title-col">
<h2 i18n>APPEARANCE</h2>
<div i18n class="inner-form-description">
Use <a class="link-orange" routerLink="/admin/plugins">plugins & themes</a> for more involved changes, or add slight <a class="link-orange" routerLink="/admin/config/edit-custom" fragment="advanced-configuration">customizations</a>.
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="theme">
<div class="form-group">
@ -90,14 +91,14 @@
</div>
<div class="row mt-4"> <!-- broadcast grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">BROADCAST MESSAGE</h2>
<div class="title-col">
<h2 i18n>BROADCAST MESSAGE</h2>
<div i18n class="inner-form-description">
Display a message on your instance
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="broadcastMessage">
@ -146,14 +147,14 @@
</div>
<div class="row mt-4"> <!-- new users grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">NEW USERS</h2>
<div class="title-col">
<h2 i18n>NEW USERS</h2>
<div i18n class="inner-form-description">
Manage <a class="link-orange" routerLink="/admin/users">users</a> to set their quota individually.
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="signup">
<div class="form-group">
@ -263,11 +264,11 @@
</div>
<div class="row mt-4"> <!-- videos grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">VIDEOS</h2>
<div class="title-col">
<h2 i18n>VIDEOS</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="import">
@ -375,11 +376,11 @@
</div>
<div class="row mt-4"> <!-- video channels grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">VIDEO CHANNELS</h2>
<div class="title-col">
<h2 i18n>VIDEO CHANNELS</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<div class="form-group" formGroupName="videoChannels">
<label i18n for="videoChannelsMaxPerUser">Max video channels per user</label>
@ -397,11 +398,11 @@
</div>
<div class="row mt-4"> <!-- search grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">SEARCH</h2>
<div class="title-col">
<h2 i18n>SEARCH</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="search">
<ng-container formGroupName="remoteUri">
@ -486,11 +487,11 @@
</div>
<div class="row mt-4"> <!-- import/export grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">USER IMPORT/EXPORT</h2>
<div class="title-col">
<h2 i18n>USER IMPORT/EXPORT</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="import">
<ng-container formGroupName="users">
@ -562,14 +563,14 @@
</div>
<div class="row mt-4"> <!-- federation grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">FEDERATION</h2>
<div class="title-col">
<h2 i18n>FEDERATION</h2>
<div i18n class="inner-form-description">
Manage <a class="link-orange" routerLink="/admin/follows">relations</a> with other instances.
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="followers">
<ng-container formGroupName="instance">
@ -641,11 +642,11 @@
</div>
<div class="row mt-4"> <!-- administrators grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">ADMINISTRATORS</h2>
<div class="title-col">
<h2 i18n>ADMINISTRATORS</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<div class="form-group" formGroupName="admin">
<label i18n for="adminEmail">Admin email</label>
@ -669,15 +670,15 @@
</div>
<div class="row mt-4"> <!-- Twitter grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">TWITTER</h2>
<div class="title-col">
<h2 i18n>TWITTER</h2>
<div i18n class="inner-form-description">
Provide the Twitter account representing your instance to improve link previews.
If you don't have a Twitter account, just leave the default value.
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="services">
<ng-container formGroupName="twitter">

View File

@ -151,3 +151,4 @@ ngb-tabset:not(.previews) ::ng-deep {
my-actor-banner-edit {
max-width: $form-max-width;
}

View File

@ -2,12 +2,12 @@
<ng-container formGroupName="instanceCustomHomepage">
<div class="homepage row mt-5"> <!-- homepage grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">INSTANCE HOMEPAGE</h2>
<div class="homepage pt-two-cols mt-5"> <!-- homepage grid -->
<div class="title-col">
<h2 i18n>INSTANCE HOMEPAGE</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<div class="form-group">
<label i18n for="instanceCustomHomepageContent">Homepage</label>

View File

@ -2,12 +2,12 @@
<ng-container formGroupName="instance">
<div class="row mt-5"> <!-- instance grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">INSTANCE</h2>
<div class="pt-two-cols mt-5"> <!-- instance grid -->
<div class="title-col">
<h2 i18n>INSTANCE</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<div class="form-group">
<label i18n for="avatarfile">Square icon</label>
@ -102,15 +102,15 @@
</div>
</div>
<div class="row mt-4"> <!-- moderation & nsfw grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">MODERATION & NSFW</h2>
<div class="pt-two-cols mt-4"> <!-- moderation & nsfw grid -->
<div class="title-col">
<h2 i18n>MODERATION & NSFW</h2>
<div i18n class="inner-form-description">
Manage <a class="link-orange" routerLink="/admin/users">users</a> to build a moderation team.
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<div class="form-group">
<my-peertube-checkbox inputName="instanceIsNSFW" formControlName="isNSFW">
<ng-template ptTemplate="label">
@ -180,12 +180,12 @@
</div>
</div>
<div class="row mt-4"> <!-- you and your instance grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">YOU AND YOUR INSTANCE</h2>
<div class="pt-two-cols mt-4"> <!-- you and your instance grid -->
<div class="title-col">
<h2 i18n>YOU AND YOUR INSTANCE</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<div class="form-group">
<label i18n for="instanceAdministrator">Who is behind the instance?</label><my-help helpType="markdownText"></my-help>
@ -230,12 +230,12 @@
</div>
</div>
<div class="row mt-4"> <!-- other information grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">OTHER INFORMATION</h2>
<div class="pt-two-cols mt-4"> <!-- other information grid -->
<div class="title-col">
<h2 i18n>OTHER INFORMATION</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<div class="form-group">
<label i18n for="instanceHardwareInformation">What server/hardware does the instance run on?</label>

View File

@ -1,14 +1,15 @@
<ng-container [formGroup]="form">
<div class="row mt-5">
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">LIVE</h2>
<div class="pt-two-cols mt-5">
<div class="title-col">
<h2 i18n>LIVE</h2>
<div i18n class="inner-form-description">
Enable users of your instance to stream live.
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="live">
@ -87,15 +88,15 @@
</div>
</div>
<div class="row"> <!-- transcoding live streams grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">TRANSCODING</h2>
<div class="pt-two-cols"> <!-- transcoding live streams grid -->
<div class="title-col">
<h2 i18n>TRANSCODING</h2>
<div i18n class="inner-form-description">
Same as VOD transcoding, transcoding live streams so that they are in a streamable form that any device can play. Requires a beefy CPU, and then some.
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="live">
<ng-container formGroupName="transcoding">

View File

@ -1,8 +1,8 @@
<ng-container [formGroup]="form">
<div class="row mt-4"> <!-- transcoding grid -->
<div class="col-12 col-lg-4 col-xl-3"></div>
<div class="col-12 col-lg-8">
<div class="pt-two-cols mt-4">
<div class="title-col"></div>
<div class="content-col">
<div class="callout callout-orange">
<span i18n>
@ -16,20 +16,21 @@
</div>
</div>
<div class="row mt-4"> <!-- transcoding grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">TRANSCODING</h2>
<div class="pt-two-cols mt-4">
<div class="title-col">
<h2 i18n>TRANSCODING</h2>
<div i18n class="inner-form-description">
Process uploaded videos so that they are in a streamable form that any device can play. Though costly in
resources, this is a critical part of PeerTube, so tread carefully.
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="transcoding">
<div class="col-12 col-xl-11">
<div>
<my-peertube-checkbox inputName="transcodingEnabled" formControlName="enabled" [recommended]="true">
<ng-template ptTemplate="label">
<ng-container i18n>Transcoding enabled</ng-container>
@ -209,15 +210,15 @@
</div>
</div>
<div class="row mt-2"> <!-- video studio grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">VIDEO STUDIO</h2>
<div class="pt-two-cols mt-2">
<div class="title-col">
<h2 i18n>VIDEO STUDIO</h2>
<div i18n class="inner-form-description">
Allows your users to edit their video (cut, add intro/outro, add a watermark etc)
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<ng-container formGroupName="videoStudio">
<div class="form-group" [ngClass]="getTranscodingDisabledClass()">

View File

@ -1,18 +1,18 @@
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<ol class="pt-breadcrumb">
<li class="breadcrumb-item">
<a routerLink="/admin/users" i18n>Users</a>
</li>
<ng-container *ngIf="isCreation()">
@if (isCreation()) {
<li class="breadcrumb-item active" i18n>Create</li>
</ng-container>
<ng-container *ngIf="!isCreation()">
} @else {
<li class="breadcrumb-item active" i18n>Edit</li>
<li class="breadcrumb-item active" aria-current="page">
<a *ngIf="user" [routerLink]="[ '/a', user?.username ]">{{ user?.username }}</a>
</li>
</ng-container>
}
</ol>
</nav>
@ -57,34 +57,33 @@
</div>
</ng-template>
<div class="row d-xxl-none"> <!-- hidden on large screens, as it is then displayed on the right side of the form -->
<div class="col-12 col-xl-3"></div>
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<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>
<div class="col-12 col-xl-9">
<ng-template *ngTemplateOutlet="dashboard"></ng-template>
</div>
</div>
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<div class="row mt-4"> <!-- user grid -->
<div class="col-12 col-lg-4 col-xl-3">
<div class="pt-two-cols mt-4"> <!-- user grid -->
<div class="title-col">
<div class="anchor" id="user"></div> <!-- user anchor -->
@if (isCreation()) {
<div class="section-left-column-title" i18n>NEW USER</div>
<h2 i18n>NEW USER</h2>
} @else if (user) {
<div class="section-left-column-title">
<my-actor-avatar-edit
actorType="account" [displayName]="user.account.displayName" [avatars]="user.account.avatars"
editable="false" [username]="user.username" displayUsername="false"
></my-actor-avatar-edit>
</div>
}
<h2 class="visually-hidden">EDIT USER {{ user.username }}</h2>
<my-actor-avatar-edit
actorType="account" [displayName]="user.account.displayName" [avatars]="user.account.avatars"
editable="false" [username]="user.username" displayUsername="false"
></my-actor-avatar-edit>
}
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<div class="row">
<form class="col" role="form" (ngSubmit)="formValidated()" [formGroup]="form">
<div class="form-group" *ngIf="isCreation()">
@ -206,7 +205,7 @@
</my-peertube-checkbox>
</div>
<input type="submit" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid">
<input class="peertube-button orange-button" type="submit" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid">
</form>
<div class="d-none d-xxl-block col-7">
@ -217,18 +216,18 @@
</div>
<div *ngIf="displayDangerZone()" class="row mt-4"> <!-- danger zone grid -->
<div class="col-12 col-lg-4 col-xl-3">
<div *ngIf="displayDangerZone()" class="pt-two-cols mt-5"> <!-- danger zone grid -->
<div class="title-col">
<div class="anchor" id="danger"></div> <!-- danger zone anchor -->
<div i18n class="section-left-column-title section-left-column-title-danger">DANGER ZONE</div>
<h2 i18n class="pt-title-danger">DANGER ZONE</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<div class="danger-zone">
<div class="form-group">
<div class="mb-1 fw-bold" i18n>Send a link to reset the password by email to the user</div>
<button (click)="resetPassword()" i18n>Ask for new password</button>
<button class="peertube-button" (click)="resetPassword()" i18n>Ask for new password</button>
</div>
<div class="form-group">
@ -238,7 +237,7 @@
<div *ngIf="user.twoFactorEnabled" class="form-group">
<div class="mb-1 fw-bold" i18n>This user has two factor authentication enabled</div>
<button (click)="disableTwoFactorAuth()" i18n>Disable two factor authentication</button>
<button class="peertube-button" (click)="disableTwoFactorAuth()" i18n>Disable two factor authentication</button>
</div>
</div>

View File

@ -26,30 +26,62 @@ my-select-custom-value {
display: block;
}
input[type=submit],
button {
@include peertube-button;
@include orange-button;
margin-top: 10px;
}
.danger-zone {
button {
@include peertube-button;
@include danger-button;
@include disable-outline;
display: block;
margin-top: 0;
}
}
.breadcrumb {
@include breadcrumb;
}
.dashboard {
@include dashboard;
display: flex;
flex-wrap: wrap;
margin: 0 -5px;
max-width: 900px;
> div {
box-sizing: border-box;
flex: 0 0 math.percentage(math.div(1, 3));
padding: 0 5px;
margin-bottom: 10px;
> a {
@include disable-default-a-behaviour;
text-decoration: none;
color: inherit;
display: block;
font-size: 18px;
&:active,
&:focus,
&:hover {
opacity: .8;
}
}
> a,
> div {
padding: 20px;
background: pvar(--submenuBackgroundColor);
border-radius: 4px;
box-sizing: border-box;
height: 100%;
}
}
.dashboard-num,
.dashboard-text {
text-align: center;
font-size: 130%;
color: pvar(--mainForegroundColor);
line-height: 30px;
margin-bottom: 20px;
}
.dashboard-label {
font-size: 90%;
color: pvar(--inputPlaceholderColor);
text-align: center;
}
}

View File

@ -104,7 +104,7 @@ export class VideoChannelCreateComponent extends VideoChannelEdit implements OnI
}
getFormButtonTitle () {
return $localize`Create`
return $localize`Create your channel`
}
getUsername () {

View File

@ -3,13 +3,16 @@
<div class="margin-content pt-4">
<form role="form" (ngSubmit)="formValidated()" [formGroup]="form">
<div class="row"> <!-- channel grid -->
<div class="col-12 col-lg-4 col-xl-3">
<div *ngIf="isCreation()" class="section-left-column-title" i18n>NEW CHANNEL</div>
<div *ngIf="!isCreation() && videoChannel" class="section-left-column-title" i18n>CHANNEL</div>
<div class="pt-two-cols"> <!-- channel grid -->
<div class="title-col">
@if (isCreation()) {
<h2 i18n>NEW CHANNEL</h2>
} @else {
<h2 i18n>UPDATE CHANNEL</h2>
}
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<my-actor-banner-edit
*ngIf="videoChannel" [previewImage]="isCreation()" class="d-block mb-4"
[bannerUrl]="videoChannel?.bannerUrl" (bannerChange)="onBannerChange($event)" (bannerDelete)="onBannerDelete()"
@ -79,13 +82,7 @@
></my-peertube-checkbox>
</div>
</div>
</div>
<div class="row"> <!-- submit placement block -->
<div class="col-md-7 col-xl-5"></div>
<div class="col-md-5 col-xl-5 d-inline-flex">
<input type="submit" class="peertube-button orange-button" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid">
<input type="submit" class="peertube-button orange-button mt-4" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid">
</div>
</div>
</form>

View File

@ -25,6 +25,6 @@ my-markdown-textarea {
@include peertube-select-container(340px);
}
.breadcrumb {
@include breadcrumb;
.pt-two-cols .content-col {
max-width: 500px;
}

View File

@ -2,7 +2,7 @@ import { Subscription } from 'rxjs'
import { HttpErrorResponse } from '@angular/common/http'
import { AfterViewInit, Component, OnDestroy, OnInit } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { AuthService, HooksService, Notifier, RedirectService, ServerService } from '@app/core'
import { AuthService, HooksService, Notifier, RedirectService } from '@app/core'
import { genericUploadErrorHandler } from '@app/helpers'
import {
VIDEO_CHANNEL_DESCRIPTION_VALIDATOR,
@ -11,7 +11,7 @@ import {
} from '@app/shared/form-validators/video-channel-validators'
import { FormReactiveService } from '@app/shared/shared-forms'
import { VideoChannel, VideoChannelService } from '@app/shared/shared-main'
import { HTMLServerConfig, VideoChannelUpdate } from '@peertube/peertube-models'
import { VideoChannelUpdate } from '@peertube/peertube-models'
import { VideoChannelEdit } from './video-channel-edit'
import { shallowCopy } from '@peertube/peertube-core-utils'
@ -26,7 +26,6 @@ export class VideoChannelUpdateComponent extends VideoChannelEdit implements OnI
private paramsSub: Subscription
private oldSupportField: string
private serverConfig: HTMLServerConfig
constructor (
protected formReactiveService: FormReactiveService,
@ -34,7 +33,6 @@ export class VideoChannelUpdateComponent extends VideoChannelEdit implements OnI
private notifier: Notifier,
private route: ActivatedRoute,
private videoChannelService: VideoChannelService,
private serverService: ServerService,
private redirectService: RedirectService,
private hooks: HooksService
) {
@ -42,8 +40,6 @@ export class VideoChannelUpdateComponent extends VideoChannelEdit implements OnI
}
ngOnInit () {
this.serverConfig = this.serverService.getHTMLConfig()
this.buildForm({
'display-name': VIDEO_CHANNEL_DISPLAY_NAME_VALIDATOR,
'description': VIDEO_CHANNEL_DESCRIPTION_VALIDATOR,
@ -183,7 +179,7 @@ export class VideoChannelUpdateComponent extends VideoChannelEdit implements OnI
}
getFormButtonTitle () {
return $localize`Update`
return $localize`Update ${this.videoChannel.name}`
}
isBulkUpdateVideosDisplayed () {

View File

@ -3,17 +3,17 @@
<ng-container i18n>Applications</ng-container>
</h1>
<div class="row"> <!-- built-in token grid -->
<div class="pt-two-cols"> <!-- built-in token grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">SUBSCRIPTION FEED</h2>
<div class="title-col">
<h2 i18n>SUBSCRIPTION FEED</h2>
<div i18n class="applications-description">
Use third-party feed aggregators to retrieve the list of videos from channels you subscribed to.
</div>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<div class="form-group">
<label i18n for="feed-url">Feed URL</label>
@ -27,12 +27,7 @@
<div class="form-group-description" i18n>⚠️ Never share your feed token with anyone.</div>
</div>
</div>
</div>
<input (click)="renewToken()" class="peertube-button orange-button mt-4" type="submit" i18n-value value="Renew token">
<div class="row mt-4"> <!-- submit placement block -->
<div class="col-md-7 col-xl-5"></div>
<div class="col-md-5 col-xl-5">
<input (click)="renewToken()" type="submit" i18n-value value="Renew token">
</div>
</div>

View File

@ -1,20 +1,6 @@
@use '_variables' as *;
@use '_mixins' as *;
.form-group {
.pt-two-cols .content-col {
max-width: 500px;
}
input[type=submit] {
@include peertube-button;
@include orange-button;
@include margin-left(auto);
display: flex;
+ .form-error {
@include margin-left(5px);
display: inline;
}
}

View File

@ -1,10 +1,10 @@
<div class="row">
<div class="pt-two-cols">
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">EXPORT</h2>
<div class="title-col">
<h2 i18n>EXPORT</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
@if (isExportEnabled()) {

View File

@ -1,10 +1,10 @@
<div class="row">
<div class="pt-two-cols">
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">IMPORT</h2>
<div class="title-col">
<h2 i18n>IMPORT</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
@if (isImportEnabled()) {
<p i18n>You can import an archive created by another PeerTube website.</p>

View File

@ -1,99 +1,94 @@
<h1 class="visually-hidden" i18n>Settings</h1>
<div class="row"> <!-- preview -->
<div class="col-12 col-lg-4 col-xl-3"></div>
<div class="pt-two-cols mt-3"> <!-- profile settings grid -->
<div class="title-col">
<h2 i18n>PROFILE SETTINGS</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<my-actor-avatar-edit
class="d-block mb-3"
actorType="account" [avatars]="user.account.avatars"
[displayName]="user.account.displayName" [username]="user.username" [subscribers]="user.account.followersCount"
(avatarChange)="onAvatarChange($event)" (avatarDelete)="onAvatarDelete()"
></my-actor-avatar-edit>
</div>
</div>
<div class="row mt-3"> <!-- profile settings grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">PROFILE SETTINGS</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<my-user-quota [user]="user" [userInformationLoaded]="userInformationLoaded"></my-user-quota>
<my-account-profile [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-profile>
</div>
</div>
<div class="row mt-5"> <!-- interface grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">INTERFACE</h2>
<div class="pt-two-cols mt-5"> <!-- interface grid -->
<div class="title-col">
<h2 i18n>INTERFACE</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<my-user-interface-settings [user]="user" [userInformationLoaded]="userInformationLoaded"></my-user-interface-settings>
</div>
</div>
<div class="row mt-5"> <!-- video settings grid -->
<div class="col-12 col-lg-4 col-xl-3">
<div class="pt-two-cols mt-5"> <!-- video settings grid -->
<div class="title-col">
<div class="anchor" id="video-settings"></div> <!-- video settings anchor -->
<h2 i18n class="section-left-column-title">VIDEO SETTINGS</h2>
<h2 i18n>VIDEO SETTINGS</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<my-user-video-settings [user]="user" [userInformationLoaded]="userInformationLoaded"></my-user-video-settings>
</div>
</div>
<div class="row mt-5"> <!-- notifications grid -->
<div class="col-12 col-lg-4 col-xl-3">
<div class="pt-two-cols mt-5"> <!-- notifications grid -->
<div class="title-col">
<div class="anchor" id="notifications"></div> <!-- notifications anchor -->
<h2 i18n class="section-left-column-title">NOTIFICATIONS</h2>
<h2 i18n>NOTIFICATIONS</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<my-account-notification-preferences [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-notification-preferences>
</div>
</div>
<div class="row mt-5" *ngIf="user.pluginAuth === null"> <!-- password grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">PASSWORD</h2>
<div class="pt-two-cols mt-5" *ngIf="user.pluginAuth === null"> <!-- password grid -->
<div class="title-col">
<h2 i18n>PASSWORD</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<my-account-change-password></my-account-change-password>
</div>
</div>
<div class="row mt-5" *ngIf="user.pluginAuth === null"> <!-- two factor auth grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">Two-factor authentication</h2>
<div class="pt-two-cols mt-5" *ngIf="user.pluginAuth === null"> <!-- two factor auth grid -->
<div class="title-col">
<h2 i18n>Two-factor authentication</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<my-account-two-factor-button [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-two-factor-button>
</div>
</div>
<div class="row mt-5" *ngIf="user.pluginAuth === null"> <!-- email grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title">EMAIL</h2>
<div class="pt-two-cols mt-5" *ngIf="user.pluginAuth === null"> <!-- email grid -->
<div class="title-col">
<h2 i18n>EMAIL</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<my-account-email-preferences class="d-block mb-5" [user]="user" [userInformationLoaded]="userInformationLoaded"></my-account-email-preferences>
<my-account-change-email></my-account-change-email>
</div>
</div>
<div class="row mt-5"> <!-- danger zone grid -->
<div class="col-12 col-lg-4 col-xl-3">
<h2 i18n class="section-left-column-title section-left-column-title-danger">DANGER ZONE</h2>
<div class="pt-two-cols mt-5"> <!-- danger zone grid -->
<div class="title-col">
<h2 i18n class="pt-title-danger">DANGER ZONE</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<my-account-danger-zone [user]="user"></my-account-danger-zone>
</div>
</div>

View File

@ -1,9 +1,6 @@
@use 'sass:color';
@use '_variables' as *;
@use '_mixins' as *;
@use 'bootstrap/scss/functions' as *;
.row > div {
max-width: 500px;
.content-col {
max-width: 500px;;
}

View File

@ -1,64 +1,58 @@
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<div class="margin-content">
<form role="form" (ngSubmit)="formValidated()" [formGroup]="form">
<div class="pt-two-cols">
<div class="row">
<div class="col-12 col-lg-4 col-xl-3">
<div class="section-left-column-title" i18n>NEW SYNCHRONIZATION</div>
</div>
<div class="title-col">
<h2 i18n>NEW SYNCHRONIZATION</h2>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="form-group">
<label i18n for="externalChannelUrl">Remote channel URL</label>
<div class="content-col">
<form role="form" (ngSubmit)="formValidated()" [formGroup]="form">
<div class="input-group">
<input
type="text"
id="externalChannelUrl"
i18n-placeholder
placeholder="Example: https://youtube.com/channel/UC_fancy_channel"
formControlName="externalChannelUrl"
[ngClass]="{ 'input-error': formErrors['externalChannelUrl'] }"
class="form-control"
>
</div>
<div class="form-group">
<label i18n for="externalChannelUrl">Remote channel URL</label>
<div *ngIf="formErrors['externalChannelUrl']" class="form-error" role="alert">
{{ formErrors['externalChannelUrl'] }}
</div>
<div class="input-group">
<input
type="text"
id="externalChannelUrl"
i18n-placeholder
placeholder="Example: https://youtube.com/channel/UC_fancy_channel"
formControlName="externalChannelUrl"
[ngClass]="{ 'input-error': formErrors['externalChannelUrl'] }"
class="form-control"
>
</div>
<div class="form-group">
<label i18n for="videoChannel">Video Channel</label>
<my-select-channel required [items]="userVideoChannels" formControlName="videoChannel"></my-select-channel>
<div *ngIf="formErrors['videoChannel']" class="form-error" role="alert">
{{ formErrors['videoChannel'] }}
</div>
</div>
<div class="form-group" role="radiogroup">
<label for="existingVideoStrategy" i18n>Options for existing videos on remote channel:</label>
<div class="peertube-radio-container">
<input type="radio" name="existingVideoStrategy" id="import" value="import" formControlName="existingVideoStrategy" required />
<label for="import" i18n>Import all and watch for new publications</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="existingVideoStrategy" id="doNothing" value="nothing" formControlName="existingVideoStrategy" required />
<label for="doNothing" i18n>Only watch for new publications</label>
</div>
<div *ngIf="formErrors['externalChannelUrl']" class="form-error" role="alert">
{{ formErrors['externalChannelUrl'] }}
</div>
</div>
</div>
<div class="row"> <!-- submit placement block -->
<div class="col-md-7 col-xl-5"></div>
<div class="col-md-5 col-xl-5 d-inline-flex">
<input type="submit" class="peertube-button orange-button ms-auto" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid">
<div class="form-group">
<label i18n for="videoChannel">Video Channel</label>
<my-select-channel required [items]="userVideoChannels" formControlName="videoChannel"></my-select-channel>
<div *ngIf="formErrors['videoChannel']" class="form-error" role="alert">
{{ formErrors['videoChannel'] }}
</div>
</div>
</div>
</form>
<div class="form-group" role="radiogroup">
<label for="existingVideoStrategy" i18n>Options for existing videos on remote channel:</label>
<div class="peertube-radio-container">
<input type="radio" name="existingVideoStrategy" id="import" value="import" formControlName="existingVideoStrategy" required />
<label for="import" i18n>Import all and watch for new publications</label>
</div>
<div class="peertube-radio-container">
<input type="radio" name="existingVideoStrategy" id="doNothing" value="nothing" formControlName="existingVideoStrategy" required />
<label for="doNothing" i18n>Only watch for new publications</label>
</div>
</div>
<input type="submit" class="peertube-button orange-button" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid">
</form>
</div>
</div>

View File

@ -1,34 +1,44 @@
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a routerLink="/my-library/video-playlists" i18n>My Playlists</a>
</li>
<ng-container *ngIf="isCreation()">
<li class="breadcrumb-item active" i18n>Create</li>
</ng-container>
<ng-container *ngIf="!isCreation()">
<li class="breadcrumb-item active" i18n>Edit</li>
<li class="breadcrumb-item active" aria-current="page">
<a *ngIf="videoPlaylistToUpdate" [routerLink]="[ '/my-library/video-playlists/update', videoPlaylistToUpdate?.uuid ]">{{ videoPlaylistToUpdate?.displayName }}</a>
</li>
</ng-container>
</ol>
</nav>
<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<form role="form" (ngSubmit)="formValidated()" [formGroup]="form">
<div class="pt-two-cols"> <!-- playlist grid -->
<div class="title-col">
<nav aria-label="breadcrumb">
<ol class="pt-breadcrumb">
<li class="breadcrumb-item">
<a routerLink="/my-library/video-playlists" i18n>My Playlists</a>
</li>
<div class="row"> <!-- playlist grid -->
<div class="col-12 col-lg-4 col-xl-3">
<div *ngIf="isCreation()" class="section-left-column-title" i18n>NEW PLAYLIST</div>
<div *ngIf="!isCreation() && videoPlaylistToUpdate" class="section-left-column-title" i18n>PLAYLIST</div>
@if (isCreation()) {
<li class="breadcrumb-item active" i18n>Create</li>
} @else {
<li class="breadcrumb-item active" i18n>Edit</li>
<li class="breadcrumb-item active" aria-current="page">
<a *ngIf="videoPlaylistToUpdate" [routerLink]="[ '/my-library/video-playlists/update', videoPlaylistToUpdate?.uuid ]">{{ videoPlaylistToUpdate?.displayName }}</a>
</li>
}
</ol>
</nav>
@if (isCreation()) {
<h2 class="visually-hidden" i18n>NEW PLAYLIST</h2>
} @else {
<h2 class="visually-hidden" i18n>UPDATE PLAYLIST</h2>
}
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="content-col">
<form role="form" (ngSubmit)="formValidated()" [formGroup]="form">
<div class="form-group">
<label for="thumbnailfile" i18n>Playlist thumbnail</label>
<my-preview-upload
i18n-inputLabel inputLabel="Edit" inputName="thumbnailfile" formControlName="thumbnailfile"
previewWidth="223px" previewHeight="122px"
></my-preview-upload>
</div>
<div class="col-md-12 col-xl-6">
<div class="form-group">
<label i18n for="displayName">Display name</label>
<input
@ -44,9 +54,7 @@
<label i18n for="description">Description</label><my-help helpType="markdownText"></my-help>
<my-markdown-textarea id="description" formControlName="description" [formError]="formErrors['description']"></my-markdown-textarea>
</div>
</div>
<div class="col-md-12 col-xl-6">
<div class="form-group">
<label i18n for="privacy">Privacy</label>
<div class="peertube-select-container">
@ -55,40 +63,21 @@
></my-select-options>
</div>
<div *ngIf="formErrors.privacy" class="form-error" role="alert">
{{ formErrors.privacy }}
</div>
<div *ngIf="formErrors.privacy" class="form-error" role="alert">{{ formErrors.privacy }}</div>
</div>
<div class="form-group">
<label for="videoChannelIdl" i18n>Channel</label>
<my-select-channel
labelForId="videoChannelIdl" [items]="userVideoChannels" formControlName="videoChannelId"
labelForId="videoChannelId" [items]="userVideoChannels" formControlName="videoChannelId"
></my-select-channel>
<div *ngIf="formErrors['videoChannelId']" class="form-error" role="alert">
{{ formErrors['videoChannelId'] }}
</div>
<div *ngIf="formErrors['videoChannelId']" class="form-error" role="alert">{{ formErrors['videoChannelId'] }}</div>
</div>
<div class="form-group">
<label for="thumbnailfile" i18n>Playlist thumbnail</label>
<my-preview-upload
i18n-inputLabel inputLabel="Edit" inputName="thumbnailfile" formControlName="thumbnailfile"
previewWidth="223px" previewHeight="122px"
></my-preview-upload>
</div>
</div>
<div class="row"> <!-- submit placement block -->
<div class="col-md-7 col-xl-5"></div>
<div class="col-md-5 col-xl-5 d-inline-flex">
<input type="submit" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid">
</div>
</div>
<input type="submit" class="peertube-button orange-button" value="{{ getFormButtonTitle() }}" [disabled]="!form.valid">
</form>
</div>
</div>
</form>

View File

@ -16,11 +16,6 @@ my-select-channel {
max-width: 340px;
}
input[type=submit] {
@include peertube-button;
@include orange-button;
}
.breadcrumb {
@include breadcrumb;
.content-col {
max-width: 500px;;
}

View File

@ -0,0 +1,46 @@
@use 'sass:color';
@use '_variables' as *;
@use '_mixins' as *;
.pt-two-cols {
@include make-row();
.title-col {
@include make-col-ready();
@include make-col(12);
@include media-breakpoint-up(lg) {
@include make-col(4);
}
@include media-breakpoint-up(xl) {
@include make-col(3);
}
h2 {
text-transform: uppercase;
color: pvar(--mainColor);
font-weight: $font-bold;
font-size: 1rem;
margin-bottom: 10px;
&.pt-title-danger {
color: color.adjust($color: #c54130, $lightness: 10%);
}
}
}
.content-col {
@include make-col-ready();
@include make-col(12);
@include media-breakpoint-up(lg) {
@include make-col(8);
}
@include media-breakpoint-up(xl) {
@include make-col(9);
}
}
}

View File

@ -80,3 +80,36 @@
flex-direction: column;
}
}
.pt-breadcrumb {
display: flex;
flex-wrap: wrap;
padding: 0;
margin-bottom: 1rem;
list-style: none;
font-weight: $font-semibold;
.breadcrumb-item {
display: flex;
a {
color: pvar(--mainColor);
}
+ .breadcrumb-item {
@include padding-left(0.5rem);
&::before {
@include padding-right(0.5rem);
display: inline-block;
color: #6c757d;
content: '/';
}
}
&.active {
color: #6c757d;
}
}
}

View File

@ -25,20 +25,6 @@
// ---------------------------------------------------------------------------
.section-left-column-title {
text-transform: uppercase;
color: pvar(--mainColor);
font-weight: $font-bold;
font-size: 1rem;
margin-bottom: 10px;
&.section-left-column-title-danger {
color: color.adjust($color: #c54130, $lightness: 10%);
}
}
// ---------------------------------------------------------------------------
.muted {
@include muted;
}

View File

@ -5,3 +5,4 @@
@use './images';
@use './_menu';
@use './_text';
@use './_layout';

View File

@ -667,91 +667,6 @@
}
}
@mixin breadcrumb {
display: flex;
flex-wrap: wrap;
padding: 0;
margin-bottom: 1rem;
list-style: none;
font-weight: $font-semibold;
.breadcrumb-item {
display: flex;
a {
color: pvar(--mainColor);
}
+ .breadcrumb-item {
@include padding-left(0.5rem);
&::before {
@include padding-right(0.5rem);
display: inline-block;
color: #6c757d;
content: '/';
}
}
&.active {
color: #6c757d;
}
}
}
@mixin dashboard {
display: flex;
flex-wrap: wrap;
margin: 0 -5px;
> div {
box-sizing: border-box;
flex: 0 0 math.percentage(math.div(1, 3));
padding: 0 5px;
margin-bottom: 10px;
> a {
@include disable-default-a-behaviour;
text-decoration: none;
color: inherit;
display: block;
font-size: 18px;
&:active,
&:focus,
&:hover {
opacity: .8;
}
}
> a,
> div {
padding: 20px;
background: pvar(--submenuBackgroundColor);
border-radius: 4px;
box-sizing: border-box;
height: 100%;
}
}
.dashboard-num,
.dashboard-text {
text-align: center;
font-size: 130%;
color: pvar(--mainForegroundColor);
line-height: 30px;
margin-bottom: 20px;
}
.dashboard-label {
font-size: 90%;
color: pvar(--inputPlaceholderColor);
text-align: center;
}
}
@mixin divider($color: pvar(--submenuBackgroundColor), $background: pvar(--mainBackgroundColor)) {
width: 95%;
border-top: .05rem solid $color;