Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Framasoft
PeerTube
PeerTube
Commits
cdeddff1
Commit
cdeddff1
authored
Apr 07, 2021
by
Chocobozzz
Committed by
Chocobozzz
Apr 08, 2021
Browse files
Add ability to update the banner
parent
282695e6
Changes
42
Hide whitespace changes
Inline
Side-by-side
client/src/app/+admin/admin.module.ts
View file @
cdeddff1
...
...
@@ -3,6 +3,7 @@ import { SelectButtonModule } from 'primeng/selectbutton'
import
{
TableModule
}
from
'
primeng/table
'
import
{
NgModule
}
from
'
@angular/core
'
import
{
SharedAbuseListModule
}
from
'
@app/shared/shared-abuse-list
'
import
{
SharedActorImageModule
}
from
'
@app/shared/shared-actor-image
'
import
{
SharedFormModule
}
from
'
@app/shared/shared-forms
'
import
{
SharedGlobalIconModule
}
from
'
@app/shared/shared-icons
'
import
{
SharedMainModule
}
from
'
@app/shared/shared-main
'
...
...
@@ -49,6 +50,7 @@ import { UserCreateComponent, UserListComponent, UserPasswordComponent, UsersCom
SharedGlobalIconModule
,
SharedAbuseListModule
,
SharedVideoCommentModule
,
SharedActorImageModule
,
TableModule
,
SelectButtonModule
,
...
...
client/src/app/+admin/users/user-edit/user-edit.component.html
View file @
cdeddff1
...
...
@@ -72,7 +72,7 @@
<div
class=
"anchor"
id=
"user"
></div>
<!-- user anchor -->
<div
*ngIf=
"isCreation()"
class=
"account-title"
i18n
>
NEW USER
</div>
<div
*ngIf=
"!isCreation() && user"
class=
"account-title"
>
<my-actor-avatar-
info
[actor]=
"user.account"
></my-actor-avatar-
info
>
<my-actor-avatar-
edit
[actor]=
"user.account"
[editable]=
"false"
[displaySubscribers]=
"false"
[displayUsername]=
"false"
></my-actor-avatar-
edit
>
</div>
</div>
...
...
client/src/app/+admin/users/user-edit/user-edit.component.scss
View file @
cdeddff1
...
...
@@ -72,11 +72,3 @@ input[type=submit], button {
@include
dashboard
;
max-width
:
900px
;
}
my-actor-avatar-info
:
:
ng-deep
{
.actor-img-edit-container
,
.actor-info-followers
,
.actor-info-username
{
display
:
none
;
}
}
client/src/app/+my-account/my-account-settings/my-account-settings.component.html
View file @
cdeddff1
...
...
@@ -3,7 +3,7 @@
<div
class=
"form-group col-12 col-lg-4 col-xl-3"
></div>
<div
class=
"form-group col-12 col-lg-8 col-xl-9"
>
<my-actor-avatar-
info
[actor]=
"user.account"
(avatarChange)=
"onAvatarChange($event)"
(avatarDelete)=
"onAvatarDelete()"
></my-actor-avatar-
info
>
<my-actor-avatar-
edit
[actor]=
"user.account"
(avatarChange)=
"onAvatarChange($event)"
(avatarDelete)=
"onAvatarDelete()"
></my-actor-avatar-
edit
>
</div>
</div>
...
...
client/src/app/+my-account/my-account.module.ts
View file @
cdeddff1
...
...
@@ -3,6 +3,7 @@ import { TableModule } from 'primeng/table'
import
{
DragDropModule
}
from
'
@angular/cdk/drag-drop
'
import
{
NgModule
}
from
'
@angular/core
'
import
{
SharedAbuseListModule
}
from
'
@app/shared/shared-abuse-list
'
import
{
SharedActorImageModule
}
from
'
@app/shared/shared-actor-image
'
import
{
SharedFormModule
}
from
'
@app/shared/shared-forms
'
import
{
SharedGlobalIconModule
}
from
'
@app/shared/shared-icons
'
import
{
SharedMainModule
}
from
'
@app/shared/shared-main
'
...
...
@@ -10,6 +11,7 @@ import { SharedModerationModule } from '@app/shared/shared-moderation'
import
{
SharedShareModal
}
from
'
@app/shared/shared-share-modal
'
import
{
SharedUserInterfaceSettingsModule
}
from
'
@app/shared/shared-user-settings
'
import
{
MyAccountAbusesListComponent
}
from
'
./my-account-abuses/my-account-abuses-list.component
'
import
{
MyAccountApplicationsComponent
}
from
'
./my-account-applications/my-account-applications.component
'
import
{
MyAccountBlocklistComponent
}
from
'
./my-account-blocklist/my-account-blocklist.component
'
import
{
MyAccountServerBlocklistComponent
}
from
'
./my-account-blocklist/my-account-server-blocklist.component
'
import
{
MyAccountNotificationsComponent
}
from
'
./my-account-notifications/my-account-notifications.component
'
...
...
@@ -20,7 +22,6 @@ import { MyAccountDangerZoneComponent } from './my-account-settings/my-account-d
import
{
MyAccountNotificationPreferencesComponent
}
from
'
./my-account-settings/my-account-notification-preferences
'
import
{
MyAccountProfileComponent
}
from
'
./my-account-settings/my-account-profile/my-account-profile.component
'
import
{
MyAccountSettingsComponent
}
from
'
./my-account-settings/my-account-settings.component
'
import
{
MyAccountApplicationsComponent
}
from
'
./my-account-applications/my-account-applications.component
'
import
{
MyAccountComponent
}
from
'
./my-account.component
'
@
NgModule
({
...
...
@@ -37,7 +38,8 @@ import { MyAccountComponent } from './my-account.component'
SharedUserInterfaceSettingsModule
,
SharedGlobalIconModule
,
SharedAbuseListModule
,
SharedShareModal
SharedShareModal
,
SharedActorImageModule
],
declarations
:
[
...
...
client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.html
View file @
cdeddff1
...
...
@@ -44,10 +44,17 @@
</div>
</div>
<my-actor-avatar-info
<h6
i18n
>
Banner image of your channel
</h6>
<my-actor-banner-edit
*ngIf=
"!isCreation() && videoChannelToUpdate"
[actor]=
"videoChannelToUpdate"
(bannerChange)=
"onBannerChange($event)"
(bannerDelete)=
"onBannerDelete()"
></my-actor-banner-edit>
<my-actor-avatar-edit
*ngIf=
"!isCreation() && videoChannelToUpdate"
[actor]=
"videoChannelToUpdate"
(avatarChange)=
"onAvatarChange($event)"
(avatarDelete)=
"onAvatarDelete()"
></my-actor-avatar-
info
>
></my-actor-avatar-
edit
>
<div
class=
"form-group"
>
<label
i18n
for=
"display-name"
>
Display name
</label>
...
...
client/src/app/+my-library/+my-video-channels/my-video-channel-edit.component.scss
View file @
cdeddff1
...
...
@@ -10,11 +10,16 @@ label {
@include
settings-big-title
;
}
my-actor-avatar-info
{
my-actor-avatar-edit
,
my-actor-banner-edit
{
display
:
block
;
margin-bottom
:
20px
;
}
my-actor-banner-edit
{
max-width
:
500px
;
}
.input-group
{
@include
peertube-input-group
(
fit-content
);
}
...
...
client/src/app/+my-library/+my-video-channels/my-video-channel-edit.ts
View file @
cdeddff1
...
...
@@ -15,6 +15,8 @@ export abstract class MyVideoChannelEdit extends FormReactive {
// We need this method so angular does not complain in child template that doesn't need this
onAvatarChange
(
formData
:
FormData
)
{
/* empty */
}
onAvatarDelete
()
{
/* empty */
}
onBannerChange
(
formData
:
FormData
)
{
/* empty */
}
onBannerDelete
()
{
/* empty */
}
// Should be implemented by the child
isBulkUpdateVideosDisplayed
()
{
...
...
client/src/app/+my-library/+my-video-channels/my-video-channel-update.component.ts
View file @
cdeddff1
import
{
Subscription
}
from
'
rxjs
'
import
{
HttpErrorResponse
}
from
'
@angular/common/http
'
import
{
Component
,
OnDestroy
,
OnInit
}
from
'
@angular/core
'
import
{
ActivatedRoute
,
Router
}
from
'
@angular/router
'
import
{
AuthService
,
Notifier
,
ServerService
}
from
'
@app/core
'
import
{
uploadErrorHandler
}
from
'
@app/helpers
'
import
{
VIDEO_CHANNEL_DESCRIPTION_VALIDATOR
,
VIDEO_CHANNEL_DISPLAY_NAME_VALIDATOR
,
...
...
@@ -11,8 +13,6 @@ import { FormValidatorService } from '@app/shared/shared-forms'
import
{
VideoChannel
,
VideoChannelService
}
from
'
@app/shared/shared-main
'
import
{
ServerConfig
,
VideoChannelUpdate
}
from
'
@shared/models
'
import
{
MyVideoChannelEdit
}
from
'
./my-video-channel-edit
'
import
{
HttpErrorResponse
}
from
'
@angular/common/http
'
import
{
uploadErrorHandler
}
from
'
@app/helpers
'
@
Component
({
selector
:
'
my-video-channel-update
'
,
...
...
@@ -101,7 +101,7 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements
}
onAvatarChange
(
formData
:
FormData
)
{
this
.
videoChannelService
.
changeVideoChannel
Avatar
(
this
.
videoChannelToUpdate
.
name
,
formData
)
this
.
videoChannelService
.
changeVideoChannel
Image
(
this
.
videoChannelToUpdate
.
name
,
formData
,
'
avatar
'
)
.
subscribe
(
data
=>
{
this
.
notifier
.
success
(
$localize
`Avatar changed.`
)
...
...
@@ -118,7 +118,7 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements
}
onAvatarDelete
()
{
this
.
videoChannelService
.
deleteVideoChannel
Avatar
(
this
.
videoChannelToUpdate
.
name
)
this
.
videoChannelService
.
deleteVideoChannel
Image
(
this
.
videoChannelToUpdate
.
name
,
'
avatar
'
)
.
subscribe
(
data
=>
{
this
.
notifier
.
success
(
$localize
`Avatar deleted.`
)
...
...
@@ -130,6 +130,36 @@ export class MyVideoChannelUpdateComponent extends MyVideoChannelEdit implements
)
}
onBannerChange
(
formData
:
FormData
)
{
this
.
videoChannelService
.
changeVideoChannelImage
(
this
.
videoChannelToUpdate
.
name
,
formData
,
'
banner
'
)
.
subscribe
(
data
=>
{
this
.
notifier
.
success
(
$localize
`Banner changed.`
)
this
.
videoChannelToUpdate
.
updateBanner
(
data
.
banner
)
},
(
err
:
HttpErrorResponse
)
=>
uploadErrorHandler
({
err
,
name
:
$localize
`banner`
,
notifier
:
this
.
notifier
})
)
}
onBannerDelete
()
{
this
.
videoChannelService
.
deleteVideoChannelImage
(
this
.
videoChannelToUpdate
.
name
,
'
banner
'
)
.
subscribe
(
data
=>
{
this
.
notifier
.
success
(
$localize
`Banner deleted.`
)
this
.
videoChannelToUpdate
.
resetBanner
()
},
err
=>
this
.
notifier
.
error
(
err
.
message
)
)
}
get
maxAvatarSize
()
{
return
this
.
serverConfig
.
avatar
.
file
.
size
.
max
}
...
...
client/src/app/+my-library/+my-video-channels/my-video-channels.module.ts
View file @
cdeddff1
import
{
ChartModule
}
from
'
primeng/chart
'
import
{
NgModule
}
from
'
@angular/core
'
import
{
SharedActorImageModule
}
from
'
@app/shared/shared-actor-image
'
import
{
SharedFormModule
}
from
'
@app/shared/shared-forms
'
import
{
SharedGlobalIconModule
}
from
'
@app/shared/shared-icons
'
import
{
SharedMainModule
}
from
'
@app/shared/shared-main
'
...
...
@@ -16,7 +17,8 @@ import { MyVideoChannelsComponent } from './my-video-channels.component'
SharedMainModule
,
SharedFormModule
,
SharedGlobalIconModule
SharedGlobalIconModule
,
SharedActorImageModule
],
declarations
:
[
...
...
client/src/app/
shared/shared-main/account
/video-avatar-channel.component.html
→
client/src/app/
+videos/+video-watch
/video-avatar-channel.component.html
View file @
cdeddff1
File moved
client/src/app/
shared/shared-main/account
/video-avatar-channel.component.scss
→
client/src/app/
+videos/+video-watch
/video-avatar-channel.component.scss
View file @
cdeddff1
File moved
client/src/app/
shared/shared-main/account
/video-avatar-channel.component.ts
→
client/src/app/
+videos/+video-watch
/video-avatar-channel.component.ts
View file @
cdeddff1
import
{
Component
,
Input
,
OnInit
}
from
'
@angular/core
'
import
{
Video
}
from
'
../video/video.model
'
import
{
Video
}
from
'
@app/shared/shared-main/video
'
@
Component
({
selector
:
'
my-video-avatar-channel
'
,
...
...
client/src/app/+videos/+video-watch/video-watch.component.ts
View file @
cdeddff1
...
...
@@ -29,7 +29,12 @@ import { MetaService } from '@ngx-meta/core'
import
{
peertubeLocalStorage
}
from
'
@root-helpers/peertube-web-storage
'
import
{
HttpStatusCode
}
from
'
@shared/core-utils/miscs/http-error-codes
'
import
{
ServerConfig
,
ServerErrorCode
,
UserVideoRateType
,
VideoCaption
,
VideoPrivacy
,
VideoState
}
from
'
@shared/models
'
import
{
cleanupVideoWatch
,
getStoredP2PEnabled
,
getStoredTheater
,
getStoredVideoWatchHistory
}
from
'
../../../assets/player/peertube-player-local-storage
'
import
{
cleanupVideoWatch
,
getStoredP2PEnabled
,
getStoredTheater
,
getStoredVideoWatchHistory
}
from
'
../../../assets/player/peertube-player-local-storage
'
import
{
CustomizationOptions
,
P2PMediaLoaderOptions
,
...
...
client/src/app/+videos/+video-watch/video-watch.module.ts
View file @
cdeddff1
...
...
@@ -16,6 +16,7 @@ import { VideoCommentComponent } from './comment/video-comment.component'
import
{
VideoCommentsComponent
}
from
'
./comment/video-comments.component
'
import
{
RecommendationsModule
}
from
'
./recommendations/recommendations.module
'
import
{
TimestampRouteTransformerDirective
}
from
'
./timestamp-route-transformer.directive
'
import
{
VideoAvatarChannelComponent
}
from
'
./video-avatar-channel.component
'
import
{
VideoWatchPlaylistComponent
}
from
'
./video-watch-playlist.component
'
import
{
VideoWatchRoutingModule
}
from
'
./video-watch-routing.module
'
import
{
VideoWatchComponent
}
from
'
./video-watch.component
'
...
...
@@ -46,6 +47,8 @@ import { VideoWatchComponent } from './video-watch.component'
VideoCommentAddComponent
,
VideoCommentComponent
,
VideoAvatarChannelComponent
,
TimestampRouteTransformerDirective
,
TimestampRouteTransformerDirective
],
...
...
client/src/app/core/server/server.service.ts
View file @
cdeddff1
...
...
@@ -98,6 +98,12 @@ export class ServerService {
extensions
:
[]
}
},
banner
:
{
file
:
{
size
:
{
max
:
0
},
extensions
:
[]
}
},
video
:
{
image
:
{
size
:
{
max
:
0
},
...
...
client/src/app/shared/shared-actor-image/actor-avatar-edit.component.html
0 → 100644
View file @
cdeddff1
<div
class=
"actor"
*ngIf=
"actor"
>
<div
class=
"d-flex"
>
<img
[ngClass]=
"{ channel: isChannel() }"
[src]=
"actor.avatarUrl"
alt=
"Avatar"
/>
<div
class=
"actor-img-edit-container"
>
<div
*ngIf=
"editable && !hasAvatar()"
class=
"actor-img-edit-button"
[ngbTooltip]=
"avatarFormat"
placement=
"right"
container=
"body"
>
<my-global-icon
iconName=
"upload"
></my-global-icon>
<label
class=
"sr-only"
for=
"avatarfile"
i18n
>
Upload a new avatar
</label>
<input
#avatarfileInput
type=
"file"
name=
"avatarfile"
id=
"avatarfile"
[accept]=
"avatarExtensions"
(change)=
"onAvatarChange(avatarfileInput)"
/>
</div>
<div
*ngIf=
"editable && hasAvatar()"
class=
"actor-img-edit-button"
#avatarPopover
="
ngbPopover
"
[ngbPopover]=
"avatarEditContent"
popoverClass=
"popover-image-info"
autoClose=
"outside"
placement=
"right"
>
<my-global-icon
iconName=
"edit"
></my-global-icon>
<label
class=
"sr-only"
for=
"avatarMenu"
i18n
>
Change your avatar
</label>
</div>
</div>
</div>
<div
class=
"actor-info"
>
<div
class=
"actor-info-display-name"
>
{{ actor.displayName }}
</div>
<div
*ngIf=
"displayUsername"
class=
"actor-info-username"
>
{{ actor.name }}
</div>
<div
*ngIf=
"displaySubscribers"
i18n
class=
"actor-info-followers"
>
{{ actor.followersCount }} subscribers
</div>
</div>
</div>
<ng-template
#avatarEditContent
>
<div
class=
"dropdown-item c-hand"
[ngbTooltip]=
"avatarFormat"
placement=
"right"
container=
"body"
>
<my-global-icon
iconName=
"upload"
></my-global-icon>
<span
for=
"avatarfile"
i18n
>
Upload a new avatar
</span>
<input
#avatarfileInput
type=
"file"
name=
"avatarfile"
id=
"avatarfile"
[accept]=
"avatarExtensions"
(change)=
"onAvatarChange(avatarfileInput)"
/>
</div>
<div
class=
"dropdown-item c-hand"
(click)=
"deleteAvatar()"
(key.enter)=
"deleteAvatar()"
>
<my-global-icon
iconName=
"delete"
></my-global-icon>
<span
i18n
>
Remove avatar
</span>
</div>
</ng-template>
client/src/app/shared/shared-actor-image/actor-avatar-edit.component.scss
0 → 100644
View file @
cdeddff1
@import
'_variables'
;
@import
'_mixins'
;
.actor
{
display
:
flex
;
img
{
margin-right
:
15px
;
&
:not
(
.channel
)
{
@include
avatar
(
100px
);
}
&
.channel
{
@include
channel-avatar
(
100px
);
}
}
.actor-info
{
display
:
inline-flex
;
flex-direction
:
column
;
.actor-info-display-name
{
font-size
:
20px
;
font-weight
:
$font-bold
;
@media
screen
and
(
max-width
:
$small-view
)
{
font-size
:
16px
;
}
}
.actor-info-username
{
position
:
relative
;
font-size
:
14px
;
color
:
pvar
(
--
greyForegroundColor
);
}
.actor-info-followers
{
font-size
:
15px
;
padding-bottom
:
.5rem
;
}
}
}
.actor-img-edit-container
{
position
:
relative
;
width
:
0
;
}
.actor-img-edit-button
{
top
:
55px
;
right
:
45px
;
border-radius
:
50%
;
}
client/src/app/shared/shared-
main/account
/actor-avatar-
info
.component.ts
→
client/src/app/shared/shared-
actor-image
/actor-avatar-
edit
.component.ts
View file @
cdeddff1
import
{
Component
,
ElementRef
,
EventEmitter
,
Input
,
OnChanges
,
OnInit
,
Output
,
SimpleChanges
,
ViewChild
}
from
'
@angular/core
'
import
{
Component
,
ElementRef
,
EventEmitter
,
Input
,
OnInit
,
Output
,
ViewChild
}
from
'
@angular/core
'
import
{
Notifier
,
ServerService
}
from
'
@app/core
'
import
{
Account
,
VideoChannel
}
from
'
@app/shared/shared-main
'
import
{
NgbPopover
}
from
'
@ng-bootstrap/ng-bootstrap
'
import
{
getBytes
}
from
'
@root-helpers/bytes
'
import
{
Account
}
from
'
../account/account.model
'
import
{
VideoChannel
}
from
'
../video-channel/video-channel.model
'
import
{
Actor
}
from
'
./actor.model
'
@
Component
({
selector
:
'
my-actor-avatar-info
'
,
templateUrl
:
'
./actor-avatar-info.component.html
'
,
styleUrls
:
[
'
./actor-avatar-info.component.scss
'
]
selector
:
'
my-actor-avatar-edit
'
,
templateUrl
:
'
./actor-avatar-edit.component.html
'
,
styleUrls
:
[
'
./actor-image-edit.scss
'
,
'
./actor-avatar-edit.component.scss
'
]
})
export
class
ActorAvatar
Info
Component
implements
OnInit
,
OnChanges
{
export
class
ActorAvatar
Edit
Component
implements
OnInit
{
@
ViewChild
(
'
avatarfileInput
'
)
avatarfileInput
:
ElementRef
<
HTMLInputElement
>
@
ViewChild
(
'
avatarPopover
'
)
avatarPopover
:
NgbPopover
@
Input
()
actor
:
VideoChannel
|
Account
@
Input
()
editable
=
true
@
Input
()
displaySubscribers
=
true
@
Input
()
displayUsername
=
true
@
Output
()
avatarChange
=
new
EventEmitter
<
FormData
>
()
@
Output
()
avatarDelete
=
new
EventEmitter
<
void
>
()
...
...
@@ -24,8 +28,6 @@ export class ActorAvatarInfoComponent implements OnInit, OnChanges {
maxAvatarSize
=
0
avatarExtensions
=
''
private
avatarUrl
:
string
constructor
(
private
serverService
:
ServerService
,
private
notifier
:
Notifier
...
...
@@ -42,12 +44,6 @@ export class ActorAvatarInfoComponent implements OnInit, OnChanges {
})
}
ngOnChanges
(
changes
:
SimpleChanges
)
{
if
(
changes
[
'
actor
'
])
{
this
.
avatarUrl
=
Actor
.
GET_ACTOR_AVATAR_URL
(
this
.
actor
)
}
}
onAvatarChange
(
input
:
HTMLInputElement
)
{
this
.
avatarfileInput
=
new
ElementRef
(
input
)
...
...
@@ -68,7 +64,7 @@ export class ActorAvatarInfoComponent implements OnInit, OnChanges {
}
hasAvatar
()
{
return
!!
this
.
avatar
Url
return
!!
this
.
actor
.
avatar
}
isChannel
()
{
...
...
client/src/app/shared/shared-actor-image/actor-banner-edit.component.html
0 → 100644
View file @
cdeddff1
<div
class=
"actor"
*ngIf=
"actor"
>
<div
class=
"actor-img-edit-container"
>
<div
class=
"banner-placeholder"
>
<img
*ngIf=
"hasBanner()"
[src]=
"actor.bannerUrl"
alt=
"Banner"
/>
</div>
<div
*ngIf=
"!hasBanner()"
class=
"actor-img-edit-button"
[ngbTooltip]=
"bannerFormat"
placement=
"right"
container=
"body"
>
<my-global-icon
iconName=
"upload"
></my-global-icon>
<label
for=
"bannerfile"
i18n
>
Upload a new banner
</label>
<input
#bannerfileInput
type=
"file"
name=
"bannerfile"
id=
"bannerfile"
[accept]=
"bannerExtensions"
(change)=
"onBannerChange(bannerfileInput)"
/>
</div>
<div
*ngIf=
"hasBanner()"
class=
"actor-img-edit-button"
#bannerPopover
="
ngbPopover
"
[ngbPopover]=
"bannerEditContent"
popoverClass=
"popover-image-info"
autoClose=
"outside"
placement=
"right"
>
<my-global-icon
iconName=
"edit"
></my-global-icon>
<label
for=
"bannerMenu"
i18n
>
Change your banner
</label>
</div>
</div>
</div>
<ng-template
#bannerEditContent
>
<div
class=
"dropdown-item c-hand"
[ngbTooltip]=
"bannerFormat"
placement=
"right"
container=
"body"
>
<my-global-icon
iconName=
"upload"
></my-global-icon>
<span
for=
"bannerfile"
i18n
>
Upload a new banner
</span>
<input
#bannerfileInput
type=
"file"
name=
"bannerfile"
id=
"bannerfile"
[accept]=
"bannerExtensions"
(change)=
"onBannerChange(bannerfileInput)"
/>
</div>
<div
class=
"dropdown-item c-hand"
(click)=
"deleteBanner()"
(key.enter)=
"deleteBanner()"
>
<my-global-icon
iconName=
"delete"
></my-global-icon>
<span
i18n
>
Remove banner
</span>
</div>
</ng-template>
Prev
1
2
3
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment