mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-10-03 09:49:20 +02:00
Add ability to set square icon in welcome wizard
This commit is contained in:
parent
37da276f9c
commit
c9905ecd3a
11 changed files with 53 additions and 15 deletions
|
@ -16,7 +16,7 @@ import {
|
|||
import { AdminConfigCustomizationComponent } from './pages/admin-config-customization.component'
|
||||
import { AdminConfigService } from '../../shared/shared-admin/admin-config.service'
|
||||
import { AdminConfigLogoComponent } from './pages/admin-config-logo.component'
|
||||
import { InstanceLogoService } from './shared/instance-logo.service'
|
||||
import { InstanceLogoService } from '../../shared/shared-instance/instance-logo.service'
|
||||
|
||||
export const customConfigResolver: ResolveFn<CustomConfig> = (_route: ActivatedRouteSnapshot, _state: RouterStateSnapshot) => {
|
||||
return inject(AdminConfigService).getCustomConfig()
|
||||
|
|
|
@ -15,7 +15,7 @@ import { of, Subscription, switchMap, tap } from 'rxjs'
|
|||
import { AdminConfigService } from '../../../shared/shared-admin/admin-config.service'
|
||||
import { PreviewUploadComponent } from '../../../shared/shared-forms/preview-upload.component'
|
||||
import { AdminSaveBarComponent } from '../shared/admin-save-bar.component'
|
||||
import { InstanceLogoService } from '../shared/instance-logo.service'
|
||||
import { InstanceLogoService } from '../../../shared/shared-instance/instance-logo.service'
|
||||
|
||||
type Form = {
|
||||
hideInstanceName: FormControl<boolean>
|
||||
|
|
|
@ -225,7 +225,7 @@
|
|||
<div class="content-col">
|
||||
|
||||
<div class="danger-zone">
|
||||
<div class="form-group">
|
||||
<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 class="peertube-button danger-button" (click)="resetPassword()" i18n>Ask for new password</button>
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,7 @@ import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
|
|||
import { AdminConfigWizardStepperComponent } from './admin-config-wizard-stepper.component'
|
||||
import { getNoWelcomeModalLocalStorageKey } from './shared/admin-config-wizard-modal-utils'
|
||||
import { AdminConfigWizardDocumentationComponent } from './steps/admin-config-wizard-documentation.component'
|
||||
import { AdminConfigWizardEditInfoComponent, FormInfo } from './steps/admin-config-wizard-edit-info.component'
|
||||
import { AdminConfigWizardEditInfoComponent, FormEditInfo } from './steps/admin-config-wizard-edit-info.component'
|
||||
import { AdminConfigWizardFormComponent } from './steps/admin-config-wizard-form.component'
|
||||
import { AdminConfigWizardPreviewComponent } from './steps/admin-config-wizard-preview.component'
|
||||
import { AdminConfigWizardWelcomeComponent } from './steps/admin-config-wizard-welcome.component'
|
||||
|
@ -37,7 +37,7 @@ export class AdminConfigWizardModalComponent implements OnInit {
|
|||
readonly created = output()
|
||||
|
||||
usageType: UsageType
|
||||
instanceInfo: FormInfo
|
||||
instanceInfo: FormEditInfo
|
||||
|
||||
showWelcome: boolean
|
||||
dryRun: boolean
|
||||
|
|
|
@ -33,6 +33,13 @@
|
|||
<div *ngIf="formErrors.shortDescription" class="form-error" role="alert">{{ formErrors.shortDescription }}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label i18n for="avatarfile">Platform icon</label>
|
||||
<div class="form-group-description" i18n>Used in various places such as on the website, mobile application and social media</div>
|
||||
|
||||
<my-preview-upload class="avatar-preview" formControlName="avatar" inputName="avatar" displayDelete="true"></my-preview-upload>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label i18n for="primaryColor">Primary color</label>
|
||||
|
||||
|
|
|
@ -11,6 +11,11 @@ form {
|
|||
height: 190px;
|
||||
}
|
||||
|
||||
.avatar-preview {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $small-view) {
|
||||
.mascot {
|
||||
display: none;
|
||||
|
|
|
@ -11,22 +11,26 @@ import {
|
|||
FormReactiveMessagesTyped
|
||||
} from '@app/shared/form-validators/form-validator.model'
|
||||
import { FormReactiveService } from '@app/shared/shared-forms/form-reactive.service'
|
||||
import { PreviewUploadComponent } from '@app/shared/shared-forms/preview-upload.component'
|
||||
import { ColorPickerModule } from 'primeng/colorpicker'
|
||||
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
|
||||
import { findAppropriateImage } from '@peertube/peertube-core-utils'
|
||||
import { logger } from '@root-helpers/logger'
|
||||
|
||||
type Form = {
|
||||
platformName: FormControl<string>
|
||||
shortDescription: FormControl<string>
|
||||
avatar: FormControl<Blob>
|
||||
primaryColor: FormControl<string>
|
||||
}
|
||||
|
||||
export type FormInfo = FormDefaultTyped<Form>
|
||||
export type FormEditInfo = FormDefaultTyped<Form>
|
||||
|
||||
@Component({
|
||||
selector: 'my-admin-config-wizard-edit-info',
|
||||
templateUrl: './admin-config-wizard-edit-info.component.html',
|
||||
styleUrls: [ './admin-config-wizard-edit-info.component.scss', '../shared/admin-config-wizard-modal-common.scss' ],
|
||||
imports: [ CommonModule, FormsModule, ReactiveFormsModule, ColorPickerModule, CdkStepperModule, ButtonComponent ]
|
||||
imports: [ CommonModule, FormsModule, ReactiveFormsModule, ColorPickerModule, CdkStepperModule, ButtonComponent, PreviewUploadComponent ]
|
||||
})
|
||||
export class AdminConfigWizardEditInfoComponent implements OnInit {
|
||||
private server = inject(ServerService)
|
||||
|
@ -38,7 +42,7 @@ export class AdminConfigWizardEditInfoComponent implements OnInit {
|
|||
readonly showBack = input.required({ transform: booleanAttribute })
|
||||
|
||||
readonly back = output()
|
||||
readonly next = output<FormInfo>()
|
||||
readonly next = output<FormEditInfo>()
|
||||
readonly hide = output()
|
||||
|
||||
form: FormGroup<Form>
|
||||
|
@ -47,12 +51,23 @@ export class AdminConfigWizardEditInfoComponent implements OnInit {
|
|||
|
||||
ngOnInit () {
|
||||
this.buildForm()
|
||||
|
||||
const avatar = findAppropriateImage(this.server.getHTMLConfig().instance.avatars, 128)
|
||||
if (avatar) {
|
||||
fetch(avatar.fileUrl)
|
||||
.then(response => response.blob())
|
||||
.then(blob => this.form.patchValue({ avatar: blob }))
|
||||
.catch(() => {
|
||||
logger.error('Could not fetch instance avatar')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private buildForm () {
|
||||
const obj: BuildFormArgumentTyped<Form> = {
|
||||
platformName: INSTANCE_NAME_VALIDATOR,
|
||||
shortDescription: INSTANCE_SHORT_DESCRIPTION_VALIDATOR,
|
||||
avatar: null,
|
||||
primaryColor: null
|
||||
}
|
||||
|
||||
|
@ -67,7 +82,7 @@ export class AdminConfigWizardEditInfoComponent implements OnInit {
|
|||
this.validationMessages = validationMessages
|
||||
}
|
||||
|
||||
private getDefaultValues (): FormDefaultTyped<Form> {
|
||||
private getDefaultValues (): FormEditInfo {
|
||||
const config = this.server.getHTMLConfig()
|
||||
const primaryColorConfig = config.theme.customization.primaryColor
|
||||
|
||||
|
@ -78,6 +93,7 @@ export class AdminConfigWizardEditInfoComponent implements OnInit {
|
|||
return {
|
||||
platformName: config.instance.name,
|
||||
shortDescription: config.instance.shortDescription,
|
||||
avatar: undefined as Blob,
|
||||
primaryColor
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,9 @@ import { ColorPickerModule } from 'primeng/colorpicker'
|
|||
import { concatMap, from, switchMap, toArray } from 'rxjs'
|
||||
import { PartialDeep } from 'type-fest'
|
||||
import { ButtonComponent } from '../../../shared/shared-main/buttons/button.component'
|
||||
import { FormInfo } from './admin-config-wizard-edit-info.component'
|
||||
import { FormEditInfo } from './admin-config-wizard-edit-info.component'
|
||||
import { UsageType } from './usage-type/usage-type.model'
|
||||
import { InstanceLogoService } from '@app/shared/shared-instance/instance-logo.service'
|
||||
|
||||
@Component({
|
||||
selector: 'my-admin-config-wizard-preview',
|
||||
|
@ -26,7 +27,7 @@ import { UsageType } from './usage-type/usage-type.model'
|
|||
CdkStepperModule,
|
||||
ButtonComponent
|
||||
],
|
||||
providers: [ AdminConfigService, PluginApiService ]
|
||||
providers: [ AdminConfigService, PluginApiService, InstanceLogoService ]
|
||||
})
|
||||
export class AdminConfigWizardPreviewComponent implements OnChanges {
|
||||
private adminConfig = inject(AdminConfigService)
|
||||
|
@ -34,11 +35,12 @@ export class AdminConfigWizardPreviewComponent implements OnChanges {
|
|||
private notifier = inject(Notifier)
|
||||
private html = inject(HtmlRendererService)
|
||||
private server = inject(ServerService)
|
||||
private instanceLogo = inject(InstanceLogoService)
|
||||
|
||||
readonly currentStep = input.required({ transform: numberAttribute })
|
||||
readonly totalSteps = input.required({ transform: numberAttribute })
|
||||
readonly usageType = input.required<UsageType>()
|
||||
readonly instanceInfo = input.required<FormInfo>()
|
||||
readonly instanceInfo = input.required<FormEditInfo>()
|
||||
readonly dryRun = input.required({ transform: booleanAttribute })
|
||||
|
||||
readonly back = output()
|
||||
|
@ -84,6 +86,12 @@ export class AdminConfigWizardPreviewComponent implements OnChanges {
|
|||
this.updating = true
|
||||
|
||||
this.adminConfig.updateCustomConfig(this.config)
|
||||
.pipe(() => {
|
||||
const avatar = this.instanceInfo().avatar
|
||||
if (avatar) return this.instanceLogo.updateAvatar(avatar)
|
||||
|
||||
return this.instanceLogo.deleteAvatar()
|
||||
})
|
||||
.pipe(
|
||||
switchMap(() => this.server.resetConfig()),
|
||||
switchMap(() => {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { AsyncValidatorFn, FormArray, FormControl, FormGroup, ValidatorFn } from '@angular/forms'
|
||||
import { PartialDeep } from 'type-fest'
|
||||
|
||||
export type BuildFormValidator = {
|
||||
VALIDATORS: ValidatorFn[]
|
||||
|
@ -19,7 +18,7 @@ export type BuildFormArgumentTyped<Form> = ReplaceForm<Form, BuildFormValidator>
|
|||
export type FormDefault = {
|
||||
[name: string]: Blob | Date | boolean | number | number[] | string | string[] | FormDefault
|
||||
}
|
||||
export type FormDefaultTyped<Form> = PartialDeep<UnwrapForm<Form>>
|
||||
export type FormDefaultTyped<Form> = Partial<UnwrapForm<Form>>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -42,8 +41,9 @@ export type UnwrapForm<Form> = {
|
|||
[K in keyof Form]: _UnwrapForm<Form[K]>
|
||||
}
|
||||
|
||||
type _UnwrapForm<T> = T extends FormGroup<infer U> ? UnwrapForm<U> :
|
||||
type _UnwrapForm<T> = T extends FormGroup<infer U> ? Partial<UnwrapForm<U>> :
|
||||
T extends FormArray<infer U> ? _UnwrapForm<U>[] :
|
||||
T extends FormControl<Blob> ? Blob :
|
||||
T extends FormControl<infer U> ? U
|
||||
: never
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
export function findAppropriateImage<T extends { width: number, height: number }> (images: T[], wantedWidth: number) {
|
||||
if (!images || images.length === 0) return undefined
|
||||
|
||||
const imagesSorted = images.sort((a, b) => a.width - b.width)
|
||||
|
||||
for (const image of imagesSorted) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue