diff options
author | Chocobozzz <me@florianbigard.com> | 2021-04-28 11:49:34 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-04-28 11:49:34 +0200 |
commit | 746018f6b81b40e8858303662ac9ec5ce59ac6eb (patch) | |
tree | 7b115d12c1926e6283346072fe1c6adbf056abd7 /client/src/app/shared | |
parent | ec489ce2f74570f94dffb62266f4ed6f18621b3e (diff) | |
download | PeerTube-746018f6b81b40e8858303662ac9ec5ce59ac6eb.tar.gz PeerTube-746018f6b81b40e8858303662ac9ec5ce59ac6eb.tar.zst PeerTube-746018f6b81b40e8858303662ac9ec5ce59ac6eb.zip |
Refactor actor avatar display
Diffstat (limited to 'client/src/app/shared')
23 files changed, 214 insertions, 135 deletions
diff --git a/client/src/app/shared/shared-abuse-list/abuse-details.component.html b/client/src/app/shared/shared-abuse-list/abuse-details.component.html index 658d42537..f2eaeb32f 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-details.component.html +++ b/client/src/app/shared/shared-abuse-list/abuse-details.component.html | |||
@@ -10,7 +10,7 @@ | |||
10 | <a [routerLink]="[ baseRoute ]" [queryParams]="{ 'search': 'reporter:"' + abuse.reporterAccount.displayName + '"' }" | 10 | <a [routerLink]="[ baseRoute ]" [queryParams]="{ 'search': 'reporter:"' + abuse.reporterAccount.displayName + '"' }" |
11 | class="chip" | 11 | class="chip" |
12 | > | 12 | > |
13 | <my-account-avatar [account]="abuse.reporterAccount"></my-account-avatar> | 13 | <my-actor-avatar [account]="abuse.reporterAccount"></my-actor-avatar> |
14 | <div> | 14 | <div> |
15 | <span class="text-muted">{{ abuse.reporterAccount.nameWithHost }}</span> | 15 | <span class="text-muted">{{ abuse.reporterAccount.nameWithHost }}</span> |
16 | </div> | 16 | </div> |
@@ -30,7 +30,7 @@ | |||
30 | <a [routerLink]="[ baseRoute ]" [queryParams]="{ 'search': 'reportee:"' +abuse.flaggedAccount.displayName + '"' }" | 30 | <a [routerLink]="[ baseRoute ]" [queryParams]="{ 'search': 'reportee:"' +abuse.flaggedAccount.displayName + '"' }" |
31 | class="chip" | 31 | class="chip" |
32 | > | 32 | > |
33 | <my-account-avatar [account]="abuse.flaggedAccount"></my-account-avatar> | 33 | <my-actor-avatar [account]="abuse.flaggedAccount"></my-actor-avatar> |
34 | <div> | 34 | <div> |
35 | <span class="text-muted">{{ abuse.flaggedAccount ? abuse.flaggedAccount.nameWithHost : '' }}</span> | 35 | <span class="text-muted">{{ abuse.flaggedAccount ? abuse.flaggedAccount.nameWithHost : '' }}</span> |
36 | </div> | 36 | </div> |
diff --git a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html index 29b51f09c..b41bc75d4 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html +++ b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html | |||
@@ -65,7 +65,7 @@ | |||
65 | <td *ngIf="isAdminView()"> | 65 | <td *ngIf="isAdminView()"> |
66 | <a *ngIf="abuse.reporterAccount" [href]="abuse.reporterAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer"> | 66 | <a *ngIf="abuse.reporterAccount" [href]="abuse.reporterAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer"> |
67 | <div class="chip two-lines"> | 67 | <div class="chip two-lines"> |
68 | <my-account-avatar [account]="abuse.reporterAccount"></my-account-avatar> | 68 | <my-actor-avatar [account]="abuse.reporterAccount"></my-actor-avatar> |
69 | <div> | 69 | <div> |
70 | {{ abuse.reporterAccount.displayName }} | 70 | {{ abuse.reporterAccount.displayName }} |
71 | <span>{{ abuse.reporterAccount.nameWithHost }}</span> | 71 | <span>{{ abuse.reporterAccount.nameWithHost }}</span> |
diff --git a/client/src/app/shared/shared-abuse-list/shared-abuse-list.module.ts b/client/src/app/shared/shared-abuse-list/shared-abuse-list.module.ts index 19b6d456d..8f3830a17 100644 --- a/client/src/app/shared/shared-abuse-list/shared-abuse-list.module.ts +++ b/client/src/app/shared/shared-abuse-list/shared-abuse-list.module.ts | |||
@@ -10,7 +10,7 @@ import { AbuseDetailsComponent } from './abuse-details.component' | |||
10 | import { AbuseListTableComponent } from './abuse-list-table.component' | 10 | import { AbuseListTableComponent } from './abuse-list-table.component' |
11 | import { AbuseMessageModalComponent } from './abuse-message-modal.component' | 11 | import { AbuseMessageModalComponent } from './abuse-message-modal.component' |
12 | import { ModerationCommentModalComponent } from './moderation-comment-modal.component' | 12 | import { ModerationCommentModalComponent } from './moderation-comment-modal.component' |
13 | import { SharedAccountAvatarModule } from '../shared-account-avatar/shared-account-avatar.module' | 13 | import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image.module' |
14 | 14 | ||
15 | @NgModule({ | 15 | @NgModule({ |
16 | imports: [ | 16 | imports: [ |
@@ -21,7 +21,7 @@ import { SharedAccountAvatarModule } from '../shared-account-avatar/shared-accou | |||
21 | SharedModerationModule, | 21 | SharedModerationModule, |
22 | SharedGlobalIconModule, | 22 | SharedGlobalIconModule, |
23 | SharedVideoCommentModule, | 23 | SharedVideoCommentModule, |
24 | SharedAccountAvatarModule | 24 | SharedActorImageModule |
25 | ], | 25 | ], |
26 | 26 | ||
27 | declarations: [ | 27 | declarations: [ |
diff --git a/client/src/app/shared/shared-account-avatar/account-avatar.component.html b/client/src/app/shared/shared-account-avatar/account-avatar.component.html deleted file mode 100644 index 083daccfb..000000000 --- a/client/src/app/shared/shared-account-avatar/account-avatar.component.html +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | <ng-template #img> | ||
2 | <img *ngIf="avatarUrl || !initial" [class]="class" [src]="avatarUrl || defaultAvatarUrl" i18n-alt alt="Account avatar" /> | ||
3 | <div *ngIf="!avatarUrl && initial" [class]="class"> | ||
4 | <span>{{ initial }}</span> | ||
5 | </div> | ||
6 | </ng-template> | ||
7 | |||
8 | <a *ngIf="account && href" [href]="href" target="_blank" rel="noopener noreferrer" [title]="title"> | ||
9 | <ng-template *ngTemplateOutlet="img"></ng-template> | ||
10 | </a> | ||
11 | |||
12 | <a *ngIf="account && internalHref" [routerLink]="internalHref" [title]="title"> | ||
13 | <ng-template *ngTemplateOutlet="img"></ng-template> | ||
14 | </a> | ||
15 | |||
16 | <ng-container *ngIf="!account || (!href && !internalHref)"> | ||
17 | <ng-template *ngTemplateOutlet="img"></ng-template> | ||
18 | </ng-container> | ||
diff --git a/client/src/app/shared/shared-account-avatar/account-avatar.component.ts b/client/src/app/shared/shared-account-avatar/account-avatar.component.ts deleted file mode 100644 index 76b696566..000000000 --- a/client/src/app/shared/shared-account-avatar/account-avatar.component.ts +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | import { Component, Input } from '@angular/core' | ||
2 | import { Account } from '../shared-main/account/account.model' | ||
3 | |||
4 | @Component({ | ||
5 | selector: 'my-account-avatar', | ||
6 | styleUrls: [ './account-avatar.component.scss' ], | ||
7 | templateUrl: './account-avatar.component.html' | ||
8 | }) | ||
9 | export class AccountAvatarComponent { | ||
10 | @Input() account: { | ||
11 | name: string | ||
12 | avatar?: { url?: string, path: string } | ||
13 | url: string | ||
14 | } | ||
15 | @Input() size: '25' | '32' | '34' | '36' | '40' | '120' = '36' | ||
16 | |||
17 | // Use an external link | ||
18 | @Input() href: string | ||
19 | // Use routerLink | ||
20 | @Input() internalHref: string | string[] | ||
21 | |||
22 | @Input() set title (value) { | ||
23 | this._title = value | ||
24 | } | ||
25 | |||
26 | defaultAvatarUrl = Account.GET_DEFAULT_AVATAR_URL() | ||
27 | |||
28 | private _title: string | ||
29 | |||
30 | get title () { | ||
31 | return this._title || $localize`${this.account.name} (account page)` | ||
32 | } | ||
33 | |||
34 | get class () { | ||
35 | return `avatar avatar-${this.size}` + (this.avatarUrl ? '' : ` initial ${this.getColorTheme()}`) | ||
36 | } | ||
37 | |||
38 | get avatarUrl () { | ||
39 | return Account.GET_ACTOR_AVATAR_URL(this.account) | ||
40 | } | ||
41 | |||
42 | get initial () { | ||
43 | return this.account?.name.slice(0, 1) | ||
44 | } | ||
45 | |||
46 | private getColorTheme () { | ||
47 | const themes = { | ||
48 | abc: 'blue', | ||
49 | def: 'green', | ||
50 | ghi: 'purple', | ||
51 | jkl: 'gray', | ||
52 | mno: 'yellow', | ||
53 | pqr: 'orange', | ||
54 | stv: 'red', | ||
55 | wxyz: 'dark-blue' | ||
56 | } | ||
57 | |||
58 | const theme = Object.keys(themes).find(chars => chars.includes(this.initial)) | ||
59 | |||
60 | return themes[theme] | ||
61 | } | ||
62 | } | ||
diff --git a/client/src/app/shared/shared-account-avatar/index.ts b/client/src/app/shared/shared-account-avatar/index.ts deleted file mode 100644 index 40c742ba5..000000000 --- a/client/src/app/shared/shared-account-avatar/index.ts +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | export * from './account-avatar.component' | ||
2 | export * from './shared-account-avatar.module' \ No newline at end of file | ||
diff --git a/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.html b/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.html index 0829263f4..e9c5fadcf 100644 --- a/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.html +++ b/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.html | |||
@@ -1,6 +1,6 @@ | |||
1 | <div class="actor" *ngIf="actor"> | 1 | <div class="actor" *ngIf="actor"> |
2 | <div class="d-flex"> | 2 | <div class="d-flex"> |
3 | <img [ngClass]="{ channel: isChannel() }" [src]="preview || actor.avatarUrl" alt="Avatar" /> | 3 | <my-actor-avatar [channel]="getChannel()" [account]="getAccount()" [previewImage]="preview" size="100"></my-actor-avatar> |
4 | 4 | ||
5 | <div class="actor-img-edit-container"> | 5 | <div class="actor-img-edit-container"> |
6 | 6 | ||
@@ -34,6 +34,7 @@ | |||
34 | <span for="avatarfile" i18n>Upload a new avatar</span> | 34 | <span for="avatarfile" i18n>Upload a new avatar</span> |
35 | <input #avatarfileInput type="file" name="avatarfile" id="avatarfile" [accept]="avatarExtensions" (change)="onAvatarChange(avatarfileInput)"/> | 35 | <input #avatarfileInput type="file" name="avatarfile" id="avatarfile" [accept]="avatarExtensions" (change)="onAvatarChange(avatarfileInput)"/> |
36 | </div> | 36 | </div> |
37 | |||
37 | <div class="dropdown-item c-hand" (click)="deleteAvatar()" (key.enter)="deleteAvatar()"> | 38 | <div class="dropdown-item c-hand" (click)="deleteAvatar()" (key.enter)="deleteAvatar()"> |
38 | <my-global-icon iconName="delete"></my-global-icon> | 39 | <my-global-icon iconName="delete"></my-global-icon> |
39 | <span i18n>Remove avatar</span> | 40 | <span i18n>Remove avatar</span> |
diff --git a/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.scss b/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.scss index 8b0172315..08e80c3b4 100644 --- a/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.scss +++ b/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.scss | |||
@@ -4,16 +4,8 @@ | |||
4 | .actor { | 4 | .actor { |
5 | display: flex; | 5 | display: flex; |
6 | 6 | ||
7 | img { | 7 | my-actor-avatar { |
8 | margin-right: 15px; | 8 | margin-right: 15px; |
9 | |||
10 | &:not(.channel) { | ||
11 | @include avatar(100px); | ||
12 | } | ||
13 | |||
14 | &.channel { | ||
15 | @include channel-avatar(100px); | ||
16 | } | ||
17 | } | 9 | } |
18 | 10 | ||
19 | .actor-info { | 11 | .actor-info { |
diff --git a/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.ts b/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.ts index d0d269489..840946690 100644 --- a/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.ts +++ b/client/src/app/shared/shared-actor-image-edit/actor-avatar-edit.component.ts | |||
@@ -80,4 +80,16 @@ export class ActorAvatarEditComponent implements OnInit { | |||
80 | isChannel () { | 80 | isChannel () { |
81 | return !!(this.actor as VideoChannel).ownerAccount | 81 | return !!(this.actor as VideoChannel).ownerAccount |
82 | } | 82 | } |
83 | |||
84 | getChannel (): VideoChannel { | ||
85 | if (this.isChannel()) return this.actor as VideoChannel | ||
86 | |||
87 | return undefined | ||
88 | } | ||
89 | |||
90 | getAccount (): Account { | ||
91 | if (this.isChannel()) return undefined | ||
92 | |||
93 | return this.actor as Account | ||
94 | } | ||
83 | } | 95 | } |
diff --git a/client/src/app/shared/shared-actor-image-edit/shared-actor-image-edit.module.ts b/client/src/app/shared/shared-actor-image-edit/shared-actor-image-edit.module.ts index c9c6472b9..f6a397d5c 100644 --- a/client/src/app/shared/shared-actor-image-edit/shared-actor-image-edit.module.ts +++ b/client/src/app/shared/shared-actor-image-edit/shared-actor-image-edit.module.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | 1 | ||
2 | import { CommonModule } from '@angular/common' | 2 | import { CommonModule } from '@angular/common' |
3 | import { NgModule } from '@angular/core' | 3 | import { NgModule } from '@angular/core' |
4 | import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image.module' | ||
4 | import { SharedGlobalIconModule } from '../shared-icons' | 5 | import { SharedGlobalIconModule } from '../shared-icons' |
5 | import { SharedMainModule } from '../shared-main' | 6 | import { SharedMainModule } from '../shared-main' |
6 | import { ActorAvatarEditComponent } from './actor-avatar-edit.component' | 7 | import { ActorAvatarEditComponent } from './actor-avatar-edit.component' |
@@ -11,6 +12,7 @@ import { ActorBannerEditComponent } from './actor-banner-edit.component' | |||
11 | CommonModule, | 12 | CommonModule, |
12 | 13 | ||
13 | SharedMainModule, | 14 | SharedMainModule, |
15 | SharedActorImageModule, | ||
14 | SharedGlobalIconModule | 16 | SharedGlobalIconModule |
15 | ], | 17 | ], |
16 | 18 | ||
diff --git a/client/src/app/shared/shared-actor-image/actor-avatar.component.html b/client/src/app/shared/shared-actor-image/actor-avatar.component.html new file mode 100644 index 000000000..607f28e5b --- /dev/null +++ b/client/src/app/shared/shared-actor-image/actor-avatar.component.html | |||
@@ -0,0 +1,19 @@ | |||
1 | <ng-template #img> | ||
2 | <img *ngIf="previewImage || avatarUrl || !initial" [class]="class" [src]="previewImage || avatarUrl || defaultAvatarUrl" [alt]="alt" /> | ||
3 | |||
4 | <div *ngIf="!avatarUrl && initial" [class]="class"> | ||
5 | <span>{{ initial }}</span> | ||
6 | </div> | ||
7 | </ng-template> | ||
8 | |||
9 | <a *ngIf="hasActor() && href" [href]="href" target="_blank" rel="noopener noreferrer" [title]="title"> | ||
10 | <ng-template *ngTemplateOutlet="img"></ng-template> | ||
11 | </a> | ||
12 | |||
13 | <a *ngIf="hasActor() && internalHref" [routerLink]="internalHref" [title]="title"> | ||
14 | <ng-template *ngTemplateOutlet="img"></ng-template> | ||
15 | </a> | ||
16 | |||
17 | <ng-container *ngIf="!hasActor() || (!href && !internalHref)"> | ||
18 | <ng-template *ngTemplateOutlet="img"></ng-template> | ||
19 | </ng-container> | ||
diff --git a/client/src/app/shared/shared-account-avatar/account-avatar.component.scss b/client/src/app/shared/shared-actor-image/actor-avatar.component.scss index 75a4cbf86..f014dec48 100644 --- a/client/src/app/shared/shared-account-avatar/account-avatar.component.scss +++ b/client/src/app/shared/shared-actor-image/actor-avatar.component.scss | |||
@@ -1,32 +1,58 @@ | |||
1 | @import '_variables'; | 1 | @import '_variables'; |
2 | @import '_mixins'; | 2 | @import '_mixins'; |
3 | 3 | ||
4 | .avatar { | ||
5 | --avatarSize: 100%; | ||
6 | --initialFontSize: 22px; | ||
7 | |||
8 | width: var(--avatarSize); | ||
9 | height: var(--avatarSize); | ||
10 | min-width: var(--avatarSize); | ||
11 | min-height: var(--avatarSize); | ||
12 | |||
13 | &.account { | ||
14 | object-fit: cover; | ||
15 | border-radius: 50%; | ||
16 | } | ||
17 | |||
18 | &.channel { | ||
19 | border-radius: 5px; | ||
20 | } | ||
21 | } | ||
22 | |||
23 | .avatar-18 { | ||
24 | --avatarSize: 18px; | ||
25 | --initialFontSize: 13px; | ||
26 | } | ||
27 | |||
4 | .avatar-25 { | 28 | .avatar-25 { |
5 | @include avatar(25px); | 29 | --avatarSize: 25px; |
6 | } | 30 | } |
7 | 31 | ||
8 | .avatar-32 { | 32 | .avatar-32 { |
9 | @include avatar(32px); | 33 | --avatarSize: 32px; |
10 | } | 34 | } |
11 | 35 | ||
12 | .avatar-34 { | 36 | .avatar-34 { |
13 | @include avatar(34px); | 37 | --avatarSize: 34px; |
14 | } | 38 | } |
15 | 39 | ||
16 | .avatar-36 { | 40 | .avatar-36 { |
17 | @include avatar(36px); | 41 | --avatarSize: 36px; |
18 | } | 42 | } |
19 | 43 | ||
20 | .avatar-40 { | 44 | .avatar-40 { |
21 | @include avatar(40px); | 45 | --avatarSize: 40px; |
22 | } | 46 | } |
23 | 47 | ||
24 | .avatar-120 { | 48 | .avatar-100 { |
25 | @include avatar(120px); | 49 | --avatarSize: 100px; |
50 | --initialFontSize: 40px; | ||
51 | } | ||
26 | 52 | ||
27 | &.initial { | 53 | .avatar-120 { |
28 | font-size: 46px; | 54 | --avatarSize: 120px; |
29 | } | 55 | --initialFontSize: 46px; |
30 | } | 56 | } |
31 | 57 | ||
32 | a:hover { | 58 | a:hover { |
@@ -39,8 +65,7 @@ a:hover { | |||
39 | display: flex; | 65 | display: flex; |
40 | align-items: center; | 66 | align-items: center; |
41 | justify-content: center; | 67 | justify-content: center; |
42 | font-size: 22px; | 68 | font-size: var(--initialFontSize); |
43 | border-radius: 50%; | ||
44 | 69 | ||
45 | &.blue { | 70 | &.blue { |
46 | background-color: #009FD4; | 71 | background-color: #009FD4; |
diff --git a/client/src/app/shared/shared-actor-image/actor-avatar.component.ts b/client/src/app/shared/shared-actor-image/actor-avatar.component.ts new file mode 100644 index 000000000..6bb3b65fa --- /dev/null +++ b/client/src/app/shared/shared-actor-image/actor-avatar.component.ts | |||
@@ -0,0 +1,110 @@ | |||
1 | import { Component, Input } from '@angular/core' | ||
2 | import { SafeResourceUrl } from '@angular/platform-browser' | ||
3 | import { VideoChannel } from '../shared-main' | ||
4 | import { Account } from '../shared-main/account/account.model' | ||
5 | |||
6 | type ActorInput = { | ||
7 | name: string | ||
8 | avatar?: { url?: string, path: string } | ||
9 | url: string | ||
10 | } | ||
11 | |||
12 | @Component({ | ||
13 | selector: 'my-actor-avatar', | ||
14 | styleUrls: [ './actor-avatar.component.scss' ], | ||
15 | templateUrl: './actor-avatar.component.html' | ||
16 | }) | ||
17 | export class ActorAvatarComponent { | ||
18 | @Input() account: ActorInput | ||
19 | @Input() channel: ActorInput | ||
20 | |||
21 | @Input() previewImage: SafeResourceUrl | ||
22 | |||
23 | @Input() size: '18' | '25' | '32' | '34' | '36' | '40' | '100' | '120' | ||
24 | |||
25 | // Use an external link | ||
26 | @Input() href: string | ||
27 | // Use routerLink | ||
28 | @Input() internalHref: string | any[] | ||
29 | |||
30 | @Input() set title (value) { | ||
31 | this._title = value | ||
32 | } | ||
33 | |||
34 | private _title: string | ||
35 | |||
36 | get title () { | ||
37 | if (this._title) return this._title | ||
38 | if (this.account) return $localize`${this.account.name} (account page)` | ||
39 | if (this.channel) return $localize`${this.channel.name} (channel page)` | ||
40 | |||
41 | return '' | ||
42 | } | ||
43 | |||
44 | get alt () { | ||
45 | if (this.account) return $localize`Account avatar` | ||
46 | if (this.channel) return $localize`Channel avatar` | ||
47 | |||
48 | return '' | ||
49 | } | ||
50 | |||
51 | get class () { | ||
52 | const base = [ 'avatar' ] | ||
53 | |||
54 | if (this.size) base.push(`avatar-${this.size}`) | ||
55 | |||
56 | if (this.account) base.push('account') | ||
57 | else base.push('channel') | ||
58 | |||
59 | if (this.initial) { | ||
60 | base.push('initial') | ||
61 | base.push(this.getColorTheme()) | ||
62 | } | ||
63 | |||
64 | return base | ||
65 | } | ||
66 | |||
67 | get defaultAvatarUrl () { | ||
68 | if (this.account) Account.GET_DEFAULT_AVATAR_URL() | ||
69 | if (this.channel) return VideoChannel.GET_DEFAULT_AVATAR_URL() | ||
70 | |||
71 | return '' | ||
72 | } | ||
73 | |||
74 | get avatarUrl () { | ||
75 | if (this.account) return Account.GET_ACTOR_AVATAR_URL(this.account) | ||
76 | if (this.channel) return VideoChannel.GET_ACTOR_AVATAR_URL(this.account) | ||
77 | |||
78 | return '' | ||
79 | } | ||
80 | |||
81 | get initial () { | ||
82 | const name = this.account?.name | ||
83 | if (!name) return '' | ||
84 | |||
85 | return name.slice(0, 1) | ||
86 | } | ||
87 | |||
88 | hasActor () { | ||
89 | return !!this.account || !!this.channel | ||
90 | } | ||
91 | |||
92 | private getColorTheme () { | ||
93 | // Keep consistency with CSS | ||
94 | const themes = { | ||
95 | abc: 'blue', | ||
96 | def: 'green', | ||
97 | ghi: 'purple', | ||
98 | jkl: 'gray', | ||
99 | mno: 'yellow', | ||
100 | pqr: 'orange', | ||
101 | stv: 'red', | ||
102 | wxyz: 'dark-blue' | ||
103 | } | ||
104 | |||
105 | const theme = Object.keys(themes) | ||
106 | .find(chars => chars.includes(this.initial)) | ||
107 | |||
108 | return themes[theme] | ||
109 | } | ||
110 | } | ||
diff --git a/client/src/app/shared/shared-actor-image/index.ts b/client/src/app/shared/shared-actor-image/index.ts new file mode 100644 index 000000000..18a9038eb --- /dev/null +++ b/client/src/app/shared/shared-actor-image/index.ts | |||
@@ -0,0 +1 @@ | |||
export * from './shared-actor-image.module' | |||
diff --git a/client/src/app/shared/shared-account-avatar/shared-account-avatar.module.ts b/client/src/app/shared/shared-actor-image/shared-actor-image.module.ts index 17b27589f..8ea4bb2bf 100644 --- a/client/src/app/shared/shared-account-avatar/shared-account-avatar.module.ts +++ b/client/src/app/shared/shared-actor-image/shared-actor-image.module.ts | |||
@@ -2,7 +2,7 @@ | |||
2 | import { NgModule } from '@angular/core' | 2 | import { NgModule } from '@angular/core' |
3 | import { SharedGlobalIconModule } from '../shared-icons' | 3 | import { SharedGlobalIconModule } from '../shared-icons' |
4 | import { SharedMainModule } from '../shared-main/shared-main.module' | 4 | import { SharedMainModule } from '../shared-main/shared-main.module' |
5 | import { AccountAvatarComponent } from './account-avatar.component' | 5 | import { ActorAvatarComponent } from './actor-avatar.component' |
6 | 6 | ||
7 | @NgModule({ | 7 | @NgModule({ |
8 | imports: [ | 8 | imports: [ |
@@ -11,13 +11,13 @@ import { AccountAvatarComponent } from './account-avatar.component' | |||
11 | ], | 11 | ], |
12 | 12 | ||
13 | declarations: [ | 13 | declarations: [ |
14 | AccountAvatarComponent | 14 | ActorAvatarComponent |
15 | ], | 15 | ], |
16 | 16 | ||
17 | exports: [ | 17 | exports: [ |
18 | AccountAvatarComponent | 18 | ActorAvatarComponent |
19 | ], | 19 | ], |
20 | 20 | ||
21 | providers: [ ] | 21 | providers: [ ] |
22 | }) | 22 | }) |
23 | export class SharedAccountAvatarModule { } | 23 | export class SharedActorImageModule { } |
diff --git a/client/src/app/shared/shared-main/users/user-notification.model.ts b/client/src/app/shared/shared-main/users/user-notification.model.ts index 88a4811da..ed5791794 100644 --- a/client/src/app/shared/shared-main/users/user-notification.model.ts +++ b/client/src/app/shared/shared-main/users/user-notification.model.ts | |||
@@ -258,10 +258,10 @@ export class UserNotification implements UserNotificationServer { | |||
258 | } | 258 | } |
259 | 259 | ||
260 | private setAccountAvatarUrl (actor: { avatarUrl?: string, avatar?: { url?: string, path: string } }) { | 260 | private setAccountAvatarUrl (actor: { avatarUrl?: string, avatar?: { url?: string, path: string } }) { |
261 | actor.avatarUrl = Account.GET_ACTOR_AVATAR_URL(actor) | 261 | actor.avatarUrl = Account.GET_ACTOR_AVATAR_URL(actor) || Account.GET_DEFAULT_AVATAR_URL() |
262 | } | 262 | } |
263 | 263 | ||
264 | private setVideoChannelAvatarUrl (actor: { avatarUrl?: string, avatar?: { url?: string, path: string } }) { | 264 | private setVideoChannelAvatarUrl (actor: { avatarUrl?: string, avatar?: { url?: string, path: string } }) { |
265 | actor.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(actor) | 265 | actor.avatarUrl = VideoChannel.GET_ACTOR_AVATAR_URL(actor) || VideoChannel.GET_DEFAULT_AVATAR_URL() |
266 | } | 266 | } |
267 | } | 267 | } |
diff --git a/client/src/app/shared/shared-main/users/user-notifications.component.scss b/client/src/app/shared/shared-main/users/user-notifications.component.scss index 5166bd559..fa9c55ec9 100644 --- a/client/src/app/shared/shared-main/users/user-notifications.component.scss +++ b/client/src/app/shared/shared-main/users/user-notifications.component.scss | |||
@@ -29,8 +29,11 @@ | |||
29 | } | 29 | } |
30 | 30 | ||
31 | .avatar { | 31 | .avatar { |
32 | @include avatar(30px); | 32 | width: 30px; |
33 | 33 | height: 30px; | |
34 | min-width: 30px; | ||
35 | min-height: 30px; | ||
36 | border-radius: 5px; | ||
34 | margin-right: 10px; | 37 | margin-right: 10px; |
35 | } | 38 | } |
36 | 39 | ||
diff --git a/client/src/app/shared/shared-main/video-channel/video-channel.model.ts b/client/src/app/shared/shared-main/video-channel/video-channel.model.ts index 1ba3fcc0e..548725e04 100644 --- a/client/src/app/shared/shared-main/video-channel/video-channel.model.ts +++ b/client/src/app/shared/shared-main/video-channel/video-channel.model.ts | |||
@@ -25,7 +25,7 @@ export class VideoChannel extends Actor implements ServerVideoChannel { | |||
25 | viewsPerDay?: ViewsPerDate[] | 25 | viewsPerDay?: ViewsPerDate[] |
26 | 26 | ||
27 | static GET_ACTOR_AVATAR_URL (actor: object) { | 27 | static GET_ACTOR_AVATAR_URL (actor: object) { |
28 | return Actor.GET_ACTOR_AVATAR_URL(actor) || this.GET_DEFAULT_AVATAR_URL() | 28 | return Actor.GET_ACTOR_AVATAR_URL(actor) |
29 | } | 29 | } |
30 | 30 | ||
31 | static GET_ACTOR_BANNER_URL (channel: ServerVideoChannel) { | 31 | static GET_ACTOR_BANNER_URL (channel: ServerVideoChannel) { |
diff --git a/client/src/app/shared/shared-moderation/account-blocklist.component.html b/client/src/app/shared/shared-moderation/account-blocklist.component.html index 3f2f55559..e914a7c3c 100644 --- a/client/src/app/shared/shared-moderation/account-blocklist.component.html +++ b/client/src/app/shared/shared-moderation/account-blocklist.component.html | |||
@@ -38,7 +38,7 @@ | |||
38 | <td> | 38 | <td> |
39 | <a [href]="accountBlock.blockedAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer"> | 39 | <a [href]="accountBlock.blockedAccount.url" i18n-title title="Open account in a new tab" target="_blank" rel="noopener noreferrer"> |
40 | <div class="chip two-lines"> | 40 | <div class="chip two-lines"> |
41 | <my-account-avatar [account]="accountBlock.blockedAccount"></my-account-avatar> | 41 | <my-actor-avatar [account]="accountBlock.blockedAccount"></my-actor-avatar> |
42 | <div> | 42 | <div> |
43 | {{ accountBlock.blockedAccount.displayName }} | 43 | {{ accountBlock.blockedAccount.displayName }} |
44 | <span class="text-muted">{{ accountBlock.blockedAccount.nameWithHost }}</span> | 44 | <span class="text-muted">{{ accountBlock.blockedAccount.nameWithHost }}</span> |
diff --git a/client/src/app/shared/shared-moderation/shared-moderation.module.ts b/client/src/app/shared/shared-moderation/shared-moderation.module.ts index c7e201792..95213e2bd 100644 --- a/client/src/app/shared/shared-moderation/shared-moderation.module.ts +++ b/client/src/app/shared/shared-moderation/shared-moderation.module.ts | |||
@@ -13,7 +13,7 @@ import { UserBanModalComponent } from './user-ban-modal.component' | |||
13 | import { UserModerationDropdownComponent } from './user-moderation-dropdown.component' | 13 | import { UserModerationDropdownComponent } from './user-moderation-dropdown.component' |
14 | import { VideoBlockComponent } from './video-block.component' | 14 | import { VideoBlockComponent } from './video-block.component' |
15 | import { VideoBlockService } from './video-block.service' | 15 | import { VideoBlockService } from './video-block.service' |
16 | import { SharedAccountAvatarModule } from '../shared-account-avatar/shared-account-avatar.module' | 16 | import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image.module' |
17 | 17 | ||
18 | @NgModule({ | 18 | @NgModule({ |
19 | imports: [ | 19 | imports: [ |
@@ -21,7 +21,7 @@ import { SharedAccountAvatarModule } from '../shared-account-avatar/shared-accou | |||
21 | SharedFormModule, | 21 | SharedFormModule, |
22 | SharedGlobalIconModule, | 22 | SharedGlobalIconModule, |
23 | SharedVideoCommentModule, | 23 | SharedVideoCommentModule, |
24 | SharedAccountAvatarModule | 24 | SharedActorImageModule |
25 | ], | 25 | ], |
26 | 26 | ||
27 | declarations: [ | 27 | declarations: [ |
diff --git a/client/src/app/shared/shared-video-miniature/shared-video-miniature.module.ts b/client/src/app/shared/shared-video-miniature/shared-video-miniature.module.ts index 32cfdfd68..03be6d2ff 100644 --- a/client/src/app/shared/shared-video-miniature/shared-video-miniature.module.ts +++ b/client/src/app/shared/shared-video-miniature/shared-video-miniature.module.ts | |||
@@ -13,7 +13,7 @@ import { VideoDownloadComponent } from './video-download.component' | |||
13 | import { VideoMiniatureComponent } from './video-miniature.component' | 13 | import { VideoMiniatureComponent } from './video-miniature.component' |
14 | import { VideosSelectionComponent } from './videos-selection.component' | 14 | import { VideosSelectionComponent } from './videos-selection.component' |
15 | import { VideoListHeaderComponent } from './video-list-header.component' | 15 | import { VideoListHeaderComponent } from './video-list-header.component' |
16 | import { SharedAccountAvatarModule } from '../shared-account-avatar/shared-account-avatar.module' | 16 | import { SharedActorImageModule } from '../shared-actor-image/shared-actor-image.module' |
17 | 17 | ||
18 | @NgModule({ | 18 | @NgModule({ |
19 | imports: [ | 19 | imports: [ |
@@ -25,7 +25,7 @@ import { SharedAccountAvatarModule } from '../shared-account-avatar/shared-accou | |||
25 | SharedGlobalIconModule, | 25 | SharedGlobalIconModule, |
26 | SharedVideoLiveModule, | 26 | SharedVideoLiveModule, |
27 | SharedVideoModule, | 27 | SharedVideoModule, |
28 | SharedAccountAvatarModule | 28 | SharedActorImageModule |
29 | ], | 29 | ], |
30 | 30 | ||
31 | declarations: [ | 31 | declarations: [ |
diff --git a/client/src/app/shared/shared-video-miniature/video-miniature.component.html b/client/src/app/shared/shared-video-miniature/video-miniature.component.html index bc19127aa..7c4fcc491 100644 --- a/client/src/app/shared/shared-video-miniature/video-miniature.component.html +++ b/client/src/app/shared/shared-video-miniature/video-miniature.component.html | |||
@@ -10,14 +10,15 @@ | |||
10 | <div class="video-bottom"> | 10 | <div class="video-bottom"> |
11 | <div class="video-miniature-information"> | 11 | <div class="video-miniature-information"> |
12 | <div class="d-flex video-miniature-meta"> | 12 | <div class="d-flex video-miniature-meta"> |
13 | <a *ngIf="displayOptions.avatar && displayOwnerVideoChannel()" class="channel-avatar" [routerLink]="[ '/video-channels', video.byVideoChannel ]" [title]="channelLinkTitle"> | 13 | <my-actor-avatar |
14 | <img [src]="getAvatarUrl()" alt="" /> | 14 | *ngIf="displayOptions.avatar && displayOwnerVideoChannel()" [title]="channelLinkTitle" |
15 | </a> | 15 | [channel]="video.channel" size="40" [internalHref]="[ '/video-channels', video.byVideoChannel ]" |
16 | ></my-actor-avatar> | ||
16 | 17 | ||
17 | <my-account-avatar | 18 | <my-actor-avatar |
18 | *ngIf="displayOptions.avatar && displayOwnerAccount()" [title]="channelLinkTitle" | 19 | *ngIf="displayOptions.avatar && displayOwnerAccount()" [title]="channelLinkTitle" |
19 | [account]="video.account" size="40" [internalHref]="'/video-channels/' + video.byVideoChannel" | 20 | [account]="video.account" size="40" [internalHref]="[ '/video-channels', video.byVideoChannel ]" |
20 | ></my-account-avatar> | 21 | ></my-actor-avatar> |
21 | 22 | ||
22 | <div class="w-100 d-flex flex-column"> | 23 | <div class="w-100 d-flex flex-column"> |
23 | <a *ngIf="!videoHref" tabindex="-1" class="video-miniature-name" | 24 | <a *ngIf="!videoHref" tabindex="-1" class="video-miniature-name" |
diff --git a/client/src/app/shared/shared-video-miniature/video-miniature.component.scss b/client/src/app/shared/shared-video-miniature/video-miniature.component.scss index f6f2925f0..c142e2e93 100644 --- a/client/src/app/shared/shared-video-miniature/video-miniature.component.scss +++ b/client/src/app/shared/shared-video-miniature/video-miniature.component.scss | |||
@@ -12,15 +12,10 @@ $more-button-width: 40px; | |||
12 | width: calc(100% - #{$more-button-width}); | 12 | width: calc(100% - #{$more-button-width}); |
13 | } | 13 | } |
14 | 14 | ||
15 | my-account-avatar, | 15 | my-actor-avatar { |
16 | .channel-avatar { | ||
17 | margin: 10px 10px 0 0; | 16 | margin: 10px 10px 0 0; |
18 | } | 17 | } |
19 | 18 | ||
20 | .channel-avatar img{ | ||
21 | @include channel-avatar(40px); | ||
22 | } | ||
23 | |||
24 | .video-miniature-created-at-views { | 19 | .video-miniature-created-at-views { |
25 | font-size: 13px; | 20 | font-size: 13px; |
26 | } | 21 | } |