From 457bb213b273a9b206cc5654eb085cede4e916ad Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 16 Jan 2019 16:05:40 +0100 Subject: Refactor how we use icons Inject them in an angular component so we can easily change their color --- client/package.json | 1 - .../contact-admin-modal.component.html | 2 +- .../moderation-comment-modal.component.html | 5 +- .../moderation-comment-modal.component.ts | 4 +- .../users/user-list/user-list.component.html | 2 +- .../users/user-list/user-list.component.scss | 4 +- .../my-account-history.component.scss | 4 +- .../my-account-notifications.component.html | 10 +- .../my-account-notifications.component.scss | 4 +- .../my-account-accept-ownership.component.html | 3 +- .../my-account-video-channels.component.html | 2 +- .../my-account-video-channels.component.scss | 2 +- .../my-account-videos.component.html | 6 +- .../my-account-videos.component.scss | 11 +- .../video-change-ownership.component.html | 3 +- client/src/app/app.component.html | 2 + client/src/app/core/confirm/confirm.component.html | 25 --- client/src/app/core/confirm/confirm.component.scss | 17 -- client/src/app/core/confirm/confirm.component.ts | 68 -------- client/src/app/core/confirm/index.ts | 1 - client/src/app/core/core.module.ts | 4 +- client/src/app/header/header.component.html | 2 +- client/src/app/header/header.component.scss | 10 +- client/src/app/login/login.component.html | 3 +- .../app/menu/avatar-notification.component.scss | 2 +- .../src/app/menu/language-chooser.component.html | 2 +- client/src/app/search/search.component.scss | 4 +- client/src/app/shared/actor/actor.model.ts | 2 +- .../shared/buttons/action-dropdown.component.html | 2 +- .../shared/buttons/action-dropdown.component.scss | 9 +- .../src/app/shared/buttons/button.component.html | 2 +- .../src/app/shared/buttons/button.component.scss | 34 +--- client/src/app/shared/buttons/button.component.ts | 3 +- .../shared/buttons/delete-button.component.html | 2 +- .../app/shared/buttons/edit-button.component.html | 2 +- .../src/app/shared/confirm/confirm.component.html | 26 ++++ .../src/app/shared/confirm/confirm.component.scss | 17 ++ client/src/app/shared/confirm/confirm.component.ts | 68 ++++++++ .../app/shared/icons/global-icon.component.html | 0 .../app/shared/icons/global-icon.component.scss | 4 + .../src/app/shared/icons/global-icon.component.ts | 47 ++++++ client/src/app/shared/misc/help.component.html | 4 +- client/src/app/shared/misc/help.component.scss | 19 ++- .../moderation/user-ban-modal.component.html | 7 +- .../shared/moderation/user-ban-modal.component.ts | 4 +- client/src/app/shared/shared.module.ts | 8 +- .../app/shared/users/user-notification.model.ts | 37 ++--- .../app/shared/users/user-notification.service.ts | 2 - .../shared/users/user-notifications.component.html | 82 +++++++--- .../shared/users/user-notifications.component.scss | 46 ++++-- .../shared/users/user-notifications.component.ts | 14 +- client/src/app/shared/video/feed.component.html | 9 +- client/src/app/shared/video/feed.component.scss | 17 +- .../shared/video/video-miniature.component.scss | 4 +- client/src/app/shared/video/video.model.ts | 4 +- .../shared/video-caption-add-modal.component.html | 2 +- .../+video-edit/shared/video-edit.component.html | 2 +- .../+video-edit/shared/video-edit.component.scss | 17 +- .../video-import-torrent.component.html | 6 +- .../video-import-torrent.component.scss | 53 +------ .../video-import-torrent.component.ts | 3 +- .../video-import-url.component.html | 6 +- .../video-import-url.component.scss | 45 ------ .../video-import-url.component.ts | 2 +- .../video-add-components/video-send.scss | 54 +++++++ .../video-upload.component.html | 6 +- .../video-upload.component.scss | 44 +----- .../video-add-components/video-upload.component.ts | 3 +- .../videos/+video-edit/video-update.component.html | 2 +- .../comment/video-comment.component.scss | 6 +- .../modal/video-blacklist.component.html | 2 +- .../modal/video-download.component.html | 2 +- .../+video-watch/modal/video-report.component.html | 2 +- .../+video-watch/modal/video-share.component.html | 2 +- .../modal/video-support.component.html | 2 +- .../videos/+video-watch/video-watch.component.html | 24 +-- .../videos/+video-watch/video-watch.component.scss | 80 ++-------- client/src/assets/images/global/add.html | 11 ++ client/src/assets/images/global/add.svg | 13 -- client/src/assets/images/global/alert.html | 11 ++ client/src/assets/images/global/circle-tick.html | 12 ++ .../src/assets/images/global/cloud-download.html | 11 ++ client/src/assets/images/global/cloud-error.html | 11 ++ client/src/assets/images/global/cog.html | 9 ++ client/src/assets/images/global/cross.html | 10 ++ client/src/assets/images/global/cross.svg | 12 -- client/src/assets/images/global/delete-black.svg | 14 -- client/src/assets/images/global/delete-grey.svg | 14 -- client/src/assets/images/global/delete-white.svg | 14 -- client/src/assets/images/global/delete.html | 12 ++ client/src/assets/images/global/download.html | 11 ++ client/src/assets/images/global/edit-black.svg | 15 -- client/src/assets/images/global/edit-grey.svg | 15 -- client/src/assets/images/global/edit.html | 10 ++ client/src/assets/images/global/help.html | 10 ++ client/src/assets/images/global/help.svg | 12 -- client/src/assets/images/global/im-with-her.html | 10 ++ client/src/assets/images/global/im-with-her.svg | 15 -- client/src/assets/images/global/no.html | 10 ++ client/src/assets/images/global/sparkle.html | 11 ++ client/src/assets/images/global/syndication.html | 56 +++++++ client/src/assets/images/global/syndication.svg | 58 ------- client/src/assets/images/global/tick.html | 10 ++ client/src/assets/images/global/tick.svg | 12 -- client/src/assets/images/global/undo.html | 9 ++ client/src/assets/images/global/undo.svg | 11 -- client/src/assets/images/global/user-add.html | 11 ++ client/src/assets/images/global/validate.html | 12 ++ client/src/assets/images/global/validate.svg | 14 -- client/src/assets/images/header/upload-white.svg | 16 -- client/src/assets/images/video/alert.svg | 16 -- client/src/assets/images/video/blacklist.svg | 15 -- client/src/assets/images/video/dislike-grey.svg | 14 -- client/src/assets/images/video/dislike-white.svg | 14 -- client/src/assets/images/video/dislike.html | 12 ++ client/src/assets/images/video/download-black.svg | 16 -- client/src/assets/images/video/download-grey.svg | 16 -- client/src/assets/images/video/download-white.svg | 16 -- client/src/assets/images/video/heart.html | 11 ++ client/src/assets/images/video/heart.svg | 13 -- client/src/assets/images/video/like-grey.svg | 15 -- client/src/assets/images/video/like-white.svg | 15 -- client/src/assets/images/video/like.html | 10 ++ client/src/assets/images/video/more.html | 9 ++ client/src/assets/images/video/more.svg | 11 -- client/src/assets/images/video/share.html | 11 ++ client/src/assets/images/video/share.svg | 16 -- client/src/assets/images/video/upload.html | 11 ++ client/src/assets/images/video/upload.svg | 16 -- client/src/sass/application.scss | 9 +- client/src/sass/include/_mixins.scss | 49 ++++-- client/src/sass/include/_variables.scss | 9 +- client/yarn.lock | 173 --------------------- server/models/account/user-notification.ts | 158 ++++++++++++++----- shared/models/actors/actor.model.ts | 2 +- shared/models/users/user-notification.model.ts | 30 ++-- shared/models/videos/video.model.ts | 4 +- 137 files changed, 996 insertions(+), 1220 deletions(-) delete mode 100644 client/src/app/core/confirm/confirm.component.html delete mode 100644 client/src/app/core/confirm/confirm.component.scss delete mode 100644 client/src/app/core/confirm/confirm.component.ts create mode 100644 client/src/app/shared/confirm/confirm.component.html create mode 100644 client/src/app/shared/confirm/confirm.component.scss create mode 100644 client/src/app/shared/confirm/confirm.component.ts create mode 100644 client/src/app/shared/icons/global-icon.component.html create mode 100644 client/src/app/shared/icons/global-icon.component.scss create mode 100644 client/src/app/shared/icons/global-icon.component.ts delete mode 100644 client/src/app/videos/+video-edit/video-add-components/video-import-url.component.scss create mode 100644 client/src/app/videos/+video-edit/video-add-components/video-send.scss create mode 100644 client/src/assets/images/global/add.html delete mode 100644 client/src/assets/images/global/add.svg create mode 100644 client/src/assets/images/global/alert.html create mode 100644 client/src/assets/images/global/circle-tick.html create mode 100644 client/src/assets/images/global/cloud-download.html create mode 100644 client/src/assets/images/global/cloud-error.html create mode 100644 client/src/assets/images/global/cog.html create mode 100644 client/src/assets/images/global/cross.html delete mode 100644 client/src/assets/images/global/cross.svg delete mode 100644 client/src/assets/images/global/delete-black.svg delete mode 100644 client/src/assets/images/global/delete-grey.svg delete mode 100644 client/src/assets/images/global/delete-white.svg create mode 100644 client/src/assets/images/global/delete.html create mode 100644 client/src/assets/images/global/download.html delete mode 100644 client/src/assets/images/global/edit-black.svg delete mode 100644 client/src/assets/images/global/edit-grey.svg create mode 100644 client/src/assets/images/global/edit.html create mode 100644 client/src/assets/images/global/help.html delete mode 100644 client/src/assets/images/global/help.svg create mode 100644 client/src/assets/images/global/im-with-her.html delete mode 100644 client/src/assets/images/global/im-with-her.svg create mode 100644 client/src/assets/images/global/no.html create mode 100644 client/src/assets/images/global/sparkle.html create mode 100644 client/src/assets/images/global/syndication.html delete mode 100644 client/src/assets/images/global/syndication.svg create mode 100644 client/src/assets/images/global/tick.html delete mode 100644 client/src/assets/images/global/tick.svg create mode 100644 client/src/assets/images/global/undo.html delete mode 100644 client/src/assets/images/global/undo.svg create mode 100644 client/src/assets/images/global/user-add.html create mode 100644 client/src/assets/images/global/validate.html delete mode 100644 client/src/assets/images/global/validate.svg delete mode 100644 client/src/assets/images/header/upload-white.svg delete mode 100644 client/src/assets/images/video/alert.svg delete mode 100644 client/src/assets/images/video/blacklist.svg delete mode 100644 client/src/assets/images/video/dislike-grey.svg delete mode 100644 client/src/assets/images/video/dislike-white.svg create mode 100644 client/src/assets/images/video/dislike.html delete mode 100644 client/src/assets/images/video/download-black.svg delete mode 100644 client/src/assets/images/video/download-grey.svg delete mode 100644 client/src/assets/images/video/download-white.svg create mode 100644 client/src/assets/images/video/heart.html delete mode 100644 client/src/assets/images/video/heart.svg delete mode 100644 client/src/assets/images/video/like-grey.svg delete mode 100644 client/src/assets/images/video/like-white.svg create mode 100644 client/src/assets/images/video/like.html create mode 100644 client/src/assets/images/video/more.html delete mode 100644 client/src/assets/images/video/more.svg create mode 100644 client/src/assets/images/video/share.html delete mode 100644 client/src/assets/images/video/share.svg create mode 100644 client/src/assets/images/video/upload.html delete mode 100644 client/src/assets/images/video/upload.svg diff --git a/client/package.json b/client/package.json index 5fe1f3d5f..248c390fc 100644 --- a/client/package.json +++ b/client/package.json @@ -154,7 +154,6 @@ "videojs-contextmenu-ui": "^5.0.0", "videojs-dock": "^2.0.2", "videojs-hotkeys": "^0.2.21", - "webpack": "^4.17.1", "webpack-bundle-analyzer": "^3.0.2", "webpack-cli": "^3.0.8", "webtorrent": "https://github.com/webtorrent/webtorrent#e9b209c7970816fc29e0cc871157a4918d66001d", diff --git a/client/src/app/+about/about-instance/contact-admin-modal.component.html b/client/src/app/+about/about-instance/contact-admin-modal.component.html index 2b3fb32f3..b2cbd0873 100644 --- a/client/src/app/+about/about-instance/contact-admin-modal.component.html +++ b/client/src/app/+about/about-instance/contact-admin-modal.component.html @@ -1,7 +1,7 @@ @@ -53,4 +53,4 @@ - \ No newline at end of file + diff --git a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss index a735562f8..39d0cf2f7 100644 --- a/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss +++ b/client/src/app/+my-account/my-account-videos/my-account-videos.component.scss @@ -23,14 +23,11 @@ .action-button-delete-selection { @include peertube-button; @include orange-button; - } - - .icon.icon-delete-white { - @include icon(21px); + @include button-with-icon(21px); - position: relative; - top: -2px; - background-image: url('../../../assets/images/global/delete-white.svg'); + my-global-icon { + @include apply-svg-color(#fff); + } } } } diff --git a/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.html b/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.html index 7c0df850d..22f127904 100644 --- a/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.html +++ b/client/src/app/+my-account/my-account-videos/video-change-ownership/video-change-ownership.component.html @@ -1,7 +1,8 @@ + +
diff --git a/client/src/app/core/confirm/confirm.component.html b/client/src/app/core/confirm/confirm.component.html deleted file mode 100644 index 43f0c6190..000000000 --- a/client/src/app/core/confirm/confirm.component.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - diff --git a/client/src/app/core/confirm/confirm.component.scss b/client/src/app/core/confirm/confirm.component.scss deleted file mode 100644 index 93dd7926b..000000000 --- a/client/src/app/core/confirm/confirm.component.scss +++ /dev/null @@ -1,17 +0,0 @@ -@import '_variables'; -@import '_mixins'; - -.button { - padding: 0 13px; -} - -input[type=text] { - @include peertube-input-text(100%); - display: block; -} - -.form-group { - margin: 20px 0; -} - - diff --git a/client/src/app/core/confirm/confirm.component.ts b/client/src/app/core/confirm/confirm.component.ts deleted file mode 100644 index 5138b7848..000000000 --- a/client/src/app/core/confirm/confirm.component.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core' -import { ConfirmService } from './confirm.service' -import { I18n } from '@ngx-translate/i18n-polyfill' -import { NgbModal } from '@ng-bootstrap/ng-bootstrap' -import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' - -@Component({ - selector: 'my-confirm', - templateUrl: './confirm.component.html', - styleUrls: [ './confirm.component.scss' ] -}) -export class ConfirmComponent implements OnInit { - @ViewChild('confirmModal') confirmModal: ElementRef - - title = '' - message = '' - expectedInputValue = '' - inputLabel = '' - - inputValue = '' - confirmButtonText = '' - - private openedModal: NgbModalRef - - constructor ( - private modalService: NgbModal, - private confirmService: ConfirmService, - private i18n: I18n - ) { } - - ngOnInit () { - this.confirmService.showConfirm.subscribe( - ({ title, message, expectedInputValue, inputLabel, confirmButtonText }) => { - this.title = title - this.message = message - - this.inputLabel = inputLabel - this.expectedInputValue = expectedInputValue - - this.confirmButtonText = confirmButtonText || this.i18n('Confirm') - - this.showModal() - } - ) - } - - @HostListener('document:keydown.enter') - confirm () { - if (this.openedModal) this.openedModal.close() - } - - isConfirmationDisabled () { - // No input validation - if (!this.inputLabel || !this.expectedInputValue) return false - - return this.expectedInputValue !== this.inputValue - } - - showModal () { - this.inputValue = '' - - this.openedModal = this.modalService.open(this.confirmModal) - - this.openedModal.result - .then(() => this.confirmService.confirmResponse.next(true)) - .catch(() => this.confirmService.confirmResponse.next(false)) - } -} diff --git a/client/src/app/core/confirm/index.ts b/client/src/app/core/confirm/index.ts index 44aabfc13..aca591e1a 100644 --- a/client/src/app/core/confirm/index.ts +++ b/client/src/app/core/confirm/index.ts @@ -1,2 +1 @@ -export * from './confirm.component' export * from './confirm.service' diff --git a/client/src/app/core/core.module.ts b/client/src/app/core/core.module.ts index 3bc0e2885..4ef3b1e73 100644 --- a/client/src/app/core/core.module.ts +++ b/client/src/app/core/core.module.ts @@ -8,7 +8,7 @@ import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client' import { LoadingBarRouterModule } from '@ngx-loading-bar/router' import { AuthService } from './auth' -import { ConfirmComponent, ConfirmService } from './confirm' +import { ConfirmService } from './confirm' import { throwIfAlreadyLoaded } from './module-import-guard' import { LoginGuard, RedirectService, UserRightGuard } from './routing' import { ServerService } from './server' @@ -38,7 +38,6 @@ import { UserNotificationSocket } from '@app/core/notification/user-notification ], declarations: [ - ConfirmComponent, CheatSheetComponent ], @@ -48,7 +47,6 @@ import { UserNotificationSocket } from '@app/core/notification/user-notification ToastModule, - ConfirmComponent, CheatSheetComponent ], diff --git a/client/src/app/header/header.component.html b/client/src/app/header/header.component.html index c23e0c55d..46a87c79c 100644 --- a/client/src/app/header/header.component.html +++ b/client/src/app/header/header.component.html @@ -5,6 +5,6 @@ - + Upload diff --git a/client/src/app/header/header.component.scss b/client/src/app/header/header.component.scss index 2f9820665..cdc457b96 100644 --- a/client/src/app/header/header.component.scss +++ b/client/src/app/header/header.component.scss @@ -40,6 +40,7 @@ .upload-button { @include peertube-button-link; @include orange-button; + @include button-with-icon(22px, 3px, -1px); margin-right: 25px; @@ -47,15 +48,6 @@ margin-right: 0; } - .icon.icon-upload { - @include icon(22px); - - background-image: url('../../assets/images/header/upload-white.svg'); - height: 24px; - vertical-align: middle; - margin-right: 6px; - } - @media screen and (max-width: 600px) { margin-right: 10px; padding: 0 10px; diff --git a/client/src/app/login/login.component.html b/client/src/app/login/login.component.html index 9b8146624..4efe3fb22 100644 --- a/client/src/app/login/login.component.html +++ b/client/src/app/login/login.component.html @@ -55,7 +55,8 @@ diff --git a/client/src/app/shared/buttons/action-dropdown.component.scss b/client/src/app/shared/buttons/action-dropdown.component.scss index a4fcceeee..985b2ca88 100644 --- a/client/src/app/shared/buttons/action-dropdown.component.scss +++ b/client/src/app/shared/buttons/action-dropdown.component.scss @@ -24,14 +24,11 @@ } &:hover, &:active, &:focus { - background-color: $grey-color; + background-color: $grey-background-color; } - .icon-action { - @include icon(21px); - - background-image: url('../../../assets/images/video/more.svg'); - top: -1px; + .more-icon { + width: 21px; } &.small { diff --git a/client/src/app/shared/buttons/button.component.html b/client/src/app/shared/buttons/button.component.html index 87a8daccf..b6df67102 100644 --- a/client/src/app/shared/buttons/button.component.html +++ b/client/src/app/shared/buttons/button.component.html @@ -1,4 +1,4 @@ - + {{ label }} diff --git a/client/src/app/shared/buttons/button.component.scss b/client/src/app/shared/buttons/button.component.scss index 168102f09..be41669cd 100644 --- a/client/src/app/shared/buttons/button.component.scss +++ b/client/src/app/shared/buttons/button.component.scss @@ -3,41 +3,19 @@ .action-button { @include peertube-button-link; + @include button-with-icon(21px, 0, -2px); font-size: 15px; font-weight: $font-semibold; - color: #585858; - background-color: #E5E5E5; + color: $grey-foreground-color; + background-color: $grey-background-color; &:hover { - background-color: #EFEFEF; + background-color: $grey-background-hover-color; } - .icon { - @include icon(21px); - - position: relative; - top: -2px; - - &.icon-edit { - background-image: url('../../../assets/images/global/edit-grey.svg'); - } - - &.icon-delete-grey { - background-image: url('../../../assets/images/global/delete-grey.svg'); - } - - &.icon-im-with-her { - background-image: url('../../../assets/images/global/im-with-her.svg'); - } - - &.icon-tick { - background-image: url('../../../assets/images/global/tick.svg'); - } - - &.icon-cross { - background-image: url('../../../assets/images/global/cross.svg'); - } + my-global-icon { + @include apply-svg-color($grey-foreground-color); } } diff --git a/client/src/app/shared/buttons/button.component.ts b/client/src/app/shared/buttons/button.component.ts index 1a1162f09..a91e9c7eb 100644 --- a/client/src/app/shared/buttons/button.component.ts +++ b/client/src/app/shared/buttons/button.component.ts @@ -1,4 +1,5 @@ import { Component, Input } from '@angular/core' +import { GlobalIconName } from '@app/shared/icons/global-icon.component' @Component({ selector: 'my-button', @@ -9,7 +10,7 @@ import { Component, Input } from '@angular/core' export class ButtonComponent { @Input() label = '' @Input() className: string = undefined - @Input() icon: string = undefined + @Input() icon: GlobalIconName = undefined @Input() title: string = undefined getTitle () { diff --git a/client/src/app/shared/buttons/delete-button.component.html b/client/src/app/shared/buttons/delete-button.component.html index 6c55d8104..4d12a84c0 100644 --- a/client/src/app/shared/buttons/delete-button.component.html +++ b/client/src/app/shared/buttons/delete-button.component.html @@ -1,5 +1,5 @@ - + {{ label }} Delete diff --git a/client/src/app/shared/buttons/edit-button.component.html b/client/src/app/shared/buttons/edit-button.component.html index cecb780f3..da3addbae 100644 --- a/client/src/app/shared/buttons/edit-button.component.html +++ b/client/src/app/shared/buttons/edit-button.component.html @@ -1,5 +1,5 @@ - + {{ label }} Edit diff --git a/client/src/app/shared/confirm/confirm.component.html b/client/src/app/shared/confirm/confirm.component.html new file mode 100644 index 000000000..65df1cd4d --- /dev/null +++ b/client/src/app/shared/confirm/confirm.component.html @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/client/src/app/shared/confirm/confirm.component.scss b/client/src/app/shared/confirm/confirm.component.scss new file mode 100644 index 000000000..93dd7926b --- /dev/null +++ b/client/src/app/shared/confirm/confirm.component.scss @@ -0,0 +1,17 @@ +@import '_variables'; +@import '_mixins'; + +.button { + padding: 0 13px; +} + +input[type=text] { + @include peertube-input-text(100%); + display: block; +} + +.form-group { + margin: 20px 0; +} + + diff --git a/client/src/app/shared/confirm/confirm.component.ts b/client/src/app/shared/confirm/confirm.component.ts new file mode 100644 index 000000000..63c163da6 --- /dev/null +++ b/client/src/app/shared/confirm/confirm.component.ts @@ -0,0 +1,68 @@ +import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core' +import { ConfirmService } from '@app/core/confirm/confirm.service' +import { I18n } from '@ngx-translate/i18n-polyfill' +import { NgbModal } from '@ng-bootstrap/ng-bootstrap' +import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' + +@Component({ + selector: 'my-confirm', + templateUrl: './confirm.component.html', + styleUrls: [ './confirm.component.scss' ] +}) +export class ConfirmComponent implements OnInit { + @ViewChild('confirmModal') confirmModal: ElementRef + + title = '' + message = '' + expectedInputValue = '' + inputLabel = '' + + inputValue = '' + confirmButtonText = '' + + private openedModal: NgbModalRef + + constructor ( + private modalService: NgbModal, + private confirmService: ConfirmService, + private i18n: I18n + ) { } + + ngOnInit () { + this.confirmService.showConfirm.subscribe( + ({ title, message, expectedInputValue, inputLabel, confirmButtonText }) => { + this.title = title + this.message = message + + this.inputLabel = inputLabel + this.expectedInputValue = expectedInputValue + + this.confirmButtonText = confirmButtonText || this.i18n('Confirm') + + this.showModal() + } + ) + } + + @HostListener('document:keydown.enter') + confirm () { + if (this.openedModal) this.openedModal.close() + } + + isConfirmationDisabled () { + // No input validation + if (!this.inputLabel || !this.expectedInputValue) return false + + return this.expectedInputValue !== this.inputValue + } + + showModal () { + this.inputValue = '' + + this.openedModal = this.modalService.open(this.confirmModal) + + this.openedModal.result + .then(() => this.confirmService.confirmResponse.next(true)) + .catch(() => this.confirmService.confirmResponse.next(false)) + } +} diff --git a/client/src/app/shared/icons/global-icon.component.html b/client/src/app/shared/icons/global-icon.component.html new file mode 100644 index 000000000..e69de29bb diff --git a/client/src/app/shared/icons/global-icon.component.scss b/client/src/app/shared/icons/global-icon.component.scss new file mode 100644 index 000000000..6805fb6f7 --- /dev/null +++ b/client/src/app/shared/icons/global-icon.component.scss @@ -0,0 +1,4 @@ +/deep/ svg { + width: inherit; + height: inherit; +} diff --git a/client/src/app/shared/icons/global-icon.component.ts b/client/src/app/shared/icons/global-icon.component.ts new file mode 100644 index 000000000..5b9377e3e --- /dev/null +++ b/client/src/app/shared/icons/global-icon.component.ts @@ -0,0 +1,47 @@ +import { Component, ElementRef, Input, OnInit } from '@angular/core' + +const icons = { + 'add': require('../../../assets/images/global/add.html'), + 'syndication': require('../../../assets/images/global/syndication.html'), + 'help': require('../../../assets/images/global/help.html'), + 'sparkle': require('../../../assets/images/global/sparkle.html'), + 'alert': require('../../../assets/images/global/alert.html'), + 'cloud-error': require('../../../assets/images/global/cloud-error.html'), + 'user-add': require('../../../assets/images/global/user-add.html'), + 'no': require('../../../assets/images/global/no.html'), + 'cloud-download': require('../../../assets/images/global/cloud-download.html'), + 'undo': require('../../../assets/images/global/undo.html'), + 'circle-tick': require('../../../assets/images/global/circle-tick.html'), + 'cog': require('../../../assets/images/global/cog.html'), + 'download': require('../../../assets/images/global/download.html'), + 'edit': require('../../../assets/images/global/edit.html'), + 'im-with-her': require('../../../assets/images/global/im-with-her.html'), + 'delete': require('../../../assets/images/global/delete.html'), + 'cross': require('../../../assets/images/global/cross.html'), + 'validate': require('../../../assets/images/global/validate.html'), + 'dislike': require('../../../assets/images/video/dislike.html'), + 'heart': require('../../../assets/images/video/heart.html'), + 'like': require('../../../assets/images/video/like.html'), + 'more': require('../../../assets/images/video/more.html'), + 'share': require('../../../assets/images/video/share.html'), + 'upload': require('../../../assets/images/video/upload.html') +} + +export type GlobalIconName = keyof typeof icons + +@Component({ + selector: 'my-global-icon', + template: '', + styleUrls: [ './global-icon.component.scss' ] +}) +export class GlobalIconComponent implements OnInit { + @Input() iconName: GlobalIconName + + constructor (private el: ElementRef) {} + + ngOnInit () { + const nativeElement = this.el.nativeElement + + nativeElement.innerHTML = icons[this.iconName] + } +} diff --git a/client/src/app/shared/misc/help.component.html b/client/src/app/shared/misc/help.component.html index 08a2fc367..444425c9f 100644 --- a/client/src/app/shared/misc/help.component.html +++ b/client/src/app/shared/misc/help.component.html @@ -25,4 +25,6 @@ [autoClose]="true" (onHidden)="onPopoverHidden()" (onShown)="onPopoverShown()" -> +> + + diff --git a/client/src/app/shared/misc/help.component.scss b/client/src/app/shared/misc/help.component.scss index 047e53fab..4565d457a 100644 --- a/client/src/app/shared/misc/help.component.scss +++ b/client/src/app/shared/misc/help.component.scss @@ -2,13 +2,15 @@ @import '_mixins'; .help-tooltip-button { - @include icon(17px); - - position: relative; - top: -2px; - background-image: url('../../../assets/images/global/help.svg'); + cursor: pointer; border: none; - margin: 5px; + + my-global-icon { + width: 17px; + position: relative; + top: -2px; + margin: 5px; + } } /deep/ { @@ -24,8 +26,13 @@ color: #000; box-shadow: 0 0 6px rgba(0, 0, 0, 0.5); + p:last-child { + margin-bottom: 0; + } + ul { padding-left: 20px; + margin-bottom: 0; } } } diff --git a/client/src/app/shared/moderation/user-ban-modal.component.html b/client/src/app/shared/moderation/user-ban-modal.component.html index fa5cb7404..f38ea543d 100644 --- a/client/src/app/shared/moderation/user-ban-modal.component.html +++ b/client/src/app/shared/moderation/user-ban-modal.component.html @@ -1,7 +1,8 @@
- Cancel + Cancel
-
\ No newline at end of file +
diff --git a/client/src/app/shared/moderation/user-ban-modal.component.ts b/client/src/app/shared/moderation/user-ban-modal.component.ts index f755ba0e8..942765301 100644 --- a/client/src/app/shared/moderation/user-ban-modal.component.ts +++ b/client/src/app/shared/moderation/user-ban-modal.component.ts @@ -42,7 +42,7 @@ export class UserBanModalComponent extends FormReactive implements OnInit { this.openedModal = this.modalService.open(this.modal) } - hideBanUserModal () { + hide () { this.usersToBan = undefined this.openedModal.close() } @@ -60,7 +60,7 @@ export class UserBanModalComponent extends FormReactive implements OnInit { this.notifier.success(message) this.userBanned.emit(this.usersToBan) - this.hideBanUserModal() + this.hide() }, err => this.notifier.error(err.message) diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index 384f5d722..6f8625c7e 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts @@ -67,6 +67,8 @@ import { UserNotificationService } from '@app/shared/users/user-notification.ser import { UserNotificationsComponent } from '@app/shared/users/user-notifications.component' import { InstanceService } from '@app/shared/instance/instance.service' import { HtmlRendererService, LinkifierService, MarkdownService } from '@app/shared/renderer' +import { ConfirmComponent } from '@app/shared/confirm/confirm.component' +import { GlobalIconComponent } from '@app/shared/icons/global-icon.component' @NgModule({ imports: [ @@ -110,7 +112,9 @@ import { HtmlRendererService, LinkifierService, MarkdownService } from '@app/sha UserBanModalComponent, UserModerationDropdownComponent, TopMenuDropdownComponent, - UserNotificationsComponent + UserNotificationsComponent, + ConfirmComponent, + GlobalIconComponent ], exports: [ @@ -151,6 +155,8 @@ import { HtmlRendererService, LinkifierService, MarkdownService } from '@app/sha UserModerationDropdownComponent, TopMenuDropdownComponent, UserNotificationsComponent, + ConfirmComponent, + GlobalIconComponent, NumberFormatterPipe, ObjectLengthPipe, diff --git a/client/src/app/shared/users/user-notification.model.ts b/client/src/app/shared/users/user-notification.model.ts index 5ff816fb8..c5996a8a1 100644 --- a/client/src/app/shared/users/user-notification.model.ts +++ b/client/src/app/shared/users/user-notification.model.ts @@ -1,4 +1,5 @@ -import { UserNotification as UserNotificationServer, UserNotificationType, VideoInfo } from '../../../../../shared' +import { UserNotification as UserNotificationServer, UserNotificationType, VideoInfo, ActorInfo } from '../../../../../shared' +import { Actor } from '@app/shared/actor/actor.model' export class UserNotification implements UserNotificationServer { id: number @@ -6,10 +7,7 @@ export class UserNotification implements UserNotificationServer { read: boolean video?: VideoInfo & { - channel: { - id: number - displayName: string - } + channel: ActorInfo & { avatarUrl?: string } } videoImport?: { @@ -23,10 +21,7 @@ export class UserNotification implements UserNotificationServer { comment?: { id: number threadId: number - account: { - id: number - displayName: string - } + account: ActorInfo & { avatarUrl?: string } video: VideoInfo } @@ -40,18 +35,11 @@ export class UserNotification implements UserNotificationServer { video: VideoInfo } - account?: { - id: number - displayName: string - name: string - } + account?: ActorInfo & { avatarUrl?: string } actorFollow?: { id: number - follower: { - name: string - displayName: string - } + follower: ActorInfo & { avatarUrl?: string } following: { type: 'account' | 'channel' name: string @@ -76,12 +64,22 @@ export class UserNotification implements UserNotificationServer { this.read = hash.read this.video = hash.video + if (this.video) this.setAvatarUrl(this.video.channel) + this.videoImport = hash.videoImport + this.comment = hash.comment + if (this.comment) this.setAvatarUrl(this.comment.account) + this.videoAbuse = hash.videoAbuse + this.videoBlacklist = hash.videoBlacklist + this.account = hash.account + if (this.account) this.setAvatarUrl(this.account) + this.actorFollow = hash.actorFollow + if (this.actorFollow) this.setAvatarUrl(this.actorFollow.follower) this.createdAt = hash.createdAt this.updatedAt = hash.updatedAt @@ -150,4 +148,7 @@ export class UserNotification implements UserNotificationServer { return videoImport.targetUrl || videoImport.magnetUri || videoImport.torrentName } + private setAvatarUrl (actor: { avatarUrl?: string, avatar?: { path: string } }) { + actor.avatarUrl = Actor.GET_ACTOR_AVATAR_URL(actor) + } } diff --git a/client/src/app/shared/users/user-notification.service.ts b/client/src/app/shared/users/user-notification.service.ts index 67ed8f74e..f8a30955d 100644 --- a/client/src/app/shared/users/user-notification.service.ts +++ b/client/src/app/shared/users/user-notification.service.ts @@ -15,8 +15,6 @@ export class UserNotificationService { static BASE_NOTIFICATIONS_URL = environment.apiUrl + '/api/v1/users/me/notifications' static BASE_NOTIFICATION_SETTINGS = environment.apiUrl + '/api/v1/users/me/notification-settings' - private socket: SocketIOClient.Socket - constructor ( private auth: AuthService, private authHttp: HttpClient, diff --git a/client/src/app/shared/users/user-notifications.component.html b/client/src/app/shared/users/user-notifications.component.html index 86379d941..caa518e7f 100644 --- a/client/src/app/shared/users/user-notifications.component.html +++ b/client/src/app/shared/users/user-notifications.component.html @@ -1,61 +1,101 @@
You don't have notifications.
-
+
-
+ - {{ notification.video.channel.displayName }} published a new video + + +
+ {{ notification.video.channel.displayName }} published a new video +
- Your video {{ notification.video.name }} has been unblacklisted + + +
+ Your video {{ notification.video.name }} has been unblacklisted +
- Your video {{ notification.videoBlacklist.video.name }} has been blacklisted + + +
+ Your video {{ notification.videoBlacklist.video.name }} has been blacklisted +
- A new video abuse has been created on video {{ notification.videoAbuse.video.name }} + + + - {{ notification.comment.account.displayName }} commented your video {{ notification.comment.video.name }} + + +
+ {{ notification.comment.account.displayName }} commented your video {{ notification.comment.video.name }} +
- Your video {{ notification.video.name }} has been published + + +
+ Your video {{ notification.video.name }} has been published +
- Your video import {{ notification.videoImportIdentifier }} succeeded + + +
+ Your video import {{ notification.videoImportIdentifier }} succeeded +
- Your video import {{ notification.videoImportIdentifier }} failed + + +
+ Your video import {{ notification.videoImportIdentifier }} failed +
- User {{ notification.account.name }} registered on your instance + + +
+ User {{ notification.account.name }} registered on your instance +
- {{ notification.actorFollow.follower.displayName }} is following + - - your channel {{ notification.actorFollow.following.displayName }} - - your account +
+ {{ notification.actorFollow.follower.displayName }} is following + + your channel {{ notification.actorFollow.following.displayName }} + your account +
- {{ notification.comment.account.displayName }} mentioned you on video {{ notification.comment.video.name }} + + +
+ {{ notification.comment.account.displayName }} mentioned you on video {{ notification.comment.video.name }} +
-
+ -
-
-
+
{{ notification.createdAt | myFromNow }}
diff --git a/client/src/app/shared/users/user-notifications.component.scss b/client/src/app/shared/users/user-notifications.component.scss index 0ae26ea39..315d504c9 100644 --- a/client/src/app/shared/users/user-notifications.component.scss +++ b/client/src/app/shared/users/user-notifications.component.scss @@ -1,3 +1,6 @@ +@import '_variables'; +@import '_mixins'; + .no-notification { display: flex; justify-content: center; @@ -7,31 +10,42 @@ .notification { display: flex; - justify-content: space-between; align-items: center; font-size: inherit; - padding: 15px 10px; + padding: 15px 5px 15px 10px; border-bottom: 1px solid rgba(0, 0, 0, 0.10); - .mark-as-read { - min-width: 35px; + &.unread { + background-color: rgba(0, 0, 0, 0.05); + } + + my-global-icon { + width: 24px; + margin-right: 11px; + margin-left: 3px; - .glyphicon { - display: none; - cursor: pointer; - color: rgba(20, 20, 20, 0.5) - } + @include apply-svg-color(#333); } - &.unread { - background-color: rgba(0, 0, 0, 0.05); + .avatar { + @include avatar(30px); + + margin-right: 10px; + } - &:hover .mark-as-read .glyphicon { - display: block; + .message { + flex-grow: 1; - &:hover { - color: rgba(20, 20, 20, 0.8); - } + a { + font-weight: $font-semibold; } } + + .from-date { + font-size: 0.85em; + color: $grey-foreground-color; + padding-left: 5px; + min-width: 70px; + text-align: right; + } } diff --git a/client/src/app/shared/users/user-notifications.component.ts b/client/src/app/shared/users/user-notifications.component.ts index e3913ba56..b5f9fd399 100644 --- a/client/src/app/shared/users/user-notifications.component.ts +++ b/client/src/app/shared/users/user-notifications.component.ts @@ -20,11 +20,7 @@ export class UserNotificationsComponent implements OnInit { // So we can access it in the template UserNotificationType = UserNotificationType - componentPagination: ComponentPagination = { - currentPage: 1, - itemsPerPage: this.itemsPerPage, - totalItems: null - } + componentPagination: ComponentPagination constructor ( private userNotificationService: UserNotificationService, @@ -32,6 +28,12 @@ export class UserNotificationsComponent implements OnInit { ) { } ngOnInit () { + this.componentPagination = { + currentPage: 1, + itemsPerPage: this.itemsPerPage, // Reset items per page, because of the @Input() variable + totalItems: null + } + this.loadMoreNotifications() } @@ -58,6 +60,8 @@ export class UserNotificationsComponent implements OnInit { } markAsRead (notification: UserNotification) { + if (notification.read) return + this.userNotificationService.markAsRead(notification) .subscribe( () => { diff --git a/client/src/app/shared/video/feed.component.html b/client/src/app/shared/video/feed.component.html index 16116ba88..f7624ec01 100644 --- a/client/src/app/shared/video/feed.component.html +++ b/client/src/app/shared/video/feed.component.html @@ -1,10 +1,11 @@
- + class="icon-syndication" role="button" iconName="syndication" + > + {{ item.label }} -
\ No newline at end of file +
diff --git a/client/src/app/shared/video/feed.component.scss b/client/src/app/shared/video/feed.component.scss index 385764be0..ed1dc17d3 100644 --- a/client/src/app/shared/video/feed.component.scss +++ b/client/src/app/shared/video/feed.component.scss @@ -1,3 +1,4 @@ +@import '_variables'; @import '_mixins'; .video-feed { @@ -6,14 +7,12 @@ display: block; } - .icon { - @include icon(12px); + my-global-icon { + cursor: pointer; + width: 12px; + position: relative; + top: -2px; - &.icon-syndication { - position: relative; - top: -2px; - background-color: var(--mainForegroundColor); - mask-image: url('../../../assets/images/global/syndication.svg'); - } + @include apply-svg-color(var(--mainForegroundColor)) } -} \ No newline at end of file +} diff --git a/client/src/app/shared/video/video-miniature.component.scss b/client/src/app/shared/video/video-miniature.component.scss index 895879adc..f44bdf9a9 100644 --- a/client/src/app/shared/video/video-miniature.component.scss +++ b/client/src/app/shared/video/video-miniature.component.scss @@ -50,10 +50,10 @@ text-overflow: ellipsis; white-space: nowrap; font-size: 13px; - color: #585858; + color: $grey-foreground-color; &:hover { - color: #303030; + color: $grey-foreground-hover-color; } } } diff --git a/client/src/app/shared/video/video.model.ts b/client/src/app/shared/video/video.model.ts index b92c96450..6ea83d13b 100644 --- a/client/src/app/shared/video/video.model.ts +++ b/client/src/app/shared/video/video.model.ts @@ -53,7 +53,7 @@ export class Video implements VideoServerModel { displayName: string url: string host: string - avatar: Avatar + avatar?: Avatar } channel: { @@ -63,7 +63,7 @@ export class Video implements VideoServerModel { displayName: string url: string host: string - avatar: Avatar + avatar?: Avatar } userHistory?: { diff --git a/client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.html b/client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.html index 30aefdbfc..19043eee6 100644 --- a/client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.html +++ b/client/src/app/videos/+video-edit/shared/video-caption-add-modal.component.html @@ -3,7 +3,7 @@