Skip to content
GitLab
Menu
Why GitLab
Pricing
Contact Sales
Explore
Why GitLab
Pricing
Contact Sales
Explore
Sign in
Get free trial
Commits on Source (2)
[Sprint/KiltedKoala](feat): Media modal
· 0d69d125
Olivia Madrid
authored
Aug 20, 2019
and
Mark Harding
committed
Aug 20, 2019
0d69d125
Merge branch 'feat/media-modal-1539' into 'master'
· 13c6f471
Mark Harding
authored
Aug 20, 2019
[Sprint/KiltedKoala](feat): Media modal See merge request
!467
13c6f471
Hide whitespace changes
Inline
Side-by-side
src/app/common/components/overlay-modal/overlay-modal.component.scss
View file @
13c6f471
.m-overlay-modal
{
position
:
fixed
;
right
:
2vw
;
left
:
2vw
;
margin
:
auto
;
z-index
:
9999999
;
top
:
50%
;
max-height
:
98vh
;
&
:not
(
.m-overlayModal--media
)
{
position
:
fixed
;
right
:
2vw
;
left
:
2vw
;
margin
:
auto
;
z-index
:
9999999
;
top
:
50%
;
max-height
:
98vh
;
display
:
block
;
box-sizing
:
border-box
;
width
:
100%
;
max-width
:
990px
;
padding
:
(
$minds-padding
*
4
);
display
:
block
;
box-sizing
:
border-box
;
width
:
100%
;
max-width
:
990px
;
padding
:
(
$minds-padding
*
4
);
outline
:
0
;
border-radius
:
6px
;
outline
:
0
;
border-radius
:
6px
;
overflow-y
:
auto
;
-webkit-overflow-scrolling
:
touch
;
overflow-y
:
auto
;
-webkit-overflow-scrolling
:
touch
;
font-family
:
'Roboto'
,
sans-serif
;
font-family
:
'Roboto'
,
sans-serif
;
@include
m-theme
(){
color
:
themed
(
$m-grey-700
);
background
:
none
rgba
(
themed
(
$m-white
)
,
0
.95
);
}
@include
m-theme
(){
color
:
themed
(
$m-grey-700
);
background
:
none
rgba
(
themed
(
$m-white
)
,
0
.95
);
}
&
.m-overlay-modal--large
{
max-width
:
990px
;
}
&
.m-overlay-modal--large
{
max-width
:
990px
;
}
&
.m-overlay-modal--medium-large
{
max-width
:
800px
;
}
&
.m-overlay-modal--medium-large
{
max-width
:
800px
;
}
&
.m-overlay-modal--medium
{
max-width
:
600px
;
}
&
.m-overlay-modal--medium
{
max-width
:
600px
;
}
&
.m-overlay-modal--small
{
max-width
:
480px
;
padding
:
16px
;
@include
m-theme
(){
background-color
:
themed
(
$m-white
);
&
.m-overlay-modal--small
{
max-width
:
480px
;
padding
:
16px
;
@include
m-theme
(){
background-color
:
themed
(
$m-white
);
}
}
}
&
.m-overlay-modal--no-padding
{
padding
:
0px
;
&
.m-overlay-modal--no-padding
{
padding
:
0px
;
.post
{
margin
:
0px
;
.post
{
margin
:
0px
;
}
}
}
&
:not
(
.m-overlay-modal--top
)
{
transform
:
translateY
(
-50%
);
}
&
.m-overlay-modal--top
{
top
:
150px
;
}
&
:not
(
.m-overlay-modal--top
)
:not
(
.m-overlayModal--media
)
{
transform
:
translateY
(
-50%
);
}
&
.m-overlay-modal--top
{
top
:
150px
;
}
@media
screen
and
(
max-width
:
$max-mobile
)
{
padding
:
(
$minds-padding
*
2
)
(
$minds-padding
*
4
);
}
@media
screen
and
(
max-width
:
$max-mobile
)
{
padding
:
(
$minds-padding
*
2
)
(
$minds-padding
*
4
);
}
@media
screen
and
(
max-height
:
850px
)
{
max-height
:
96vh
;
}
@media
screen
and
(
max-height
:
850px
)
{
max-height
:
96vh
;
}
@media
screen
and
(
max-height
:
750px
)
{
max-height
:
98vh
;
}
@media
screen
and
(
max-height
:
750px
)
{
max-height
:
98vh
;
}
&
::-webkit-scrollbar
{
display
:
none
;
&
::-webkit-scrollbar
{
display
:
none
;
}
}
}
.m-overlay-modal--overflow
{
...
...
src/app/common/read-more/read-more.directive.ts
View file @
13c6f471
import
{
Directive
,
ElementRef
,
ContentChild
,
ChangeDetectorRef
}
from
'
@angular/core
'
;
import
{
Directive
,
ElementRef
,
ContentChild
,
ChangeDetectorRef
,
Input
}
from
'
@angular/core
'
;
import
{
ReadMoreButtonComponent
}
from
'
./button.component
'
;
@
Directive
({
...
...
@@ -8,28 +8,34 @@ export class ReadMoreDirective {
_element
:
any
;
realHeight
:
any
;
maxHeightAllowed
:
number
=
320
;
expandable
:
boolean
=
false
;
@
ContentChild
(
ReadMoreButtonComponent
,
{
'
static
'
:
false
})
button
;
@
Input
()
maxHeightAllowed
:
number
;
constructor
(
private
element
:
ElementRef
,
private
cd
:
ChangeDetectorRef
)
{
this
.
_element
=
element
.
nativeElement
;
}
ngAfterViewInit
()
{
this
.
realHeight
=
this
.
_element
.
clientHeight
;
if
(
this
.
button
&&
!
this
.
button
.
content
)
this
.
button
.
content
=
this
;
if
(
this
.
realHeight
>
this
.
maxHeightAllowed
)
{
this
.
_element
.
style
.
maxHeight
=
this
.
maxHeightAllowed
+
'
px
'
;
this
.
_element
.
style
.
position
=
'
relative
'
;
setTimeout
(()
=>
{
this
.
expandable
=
true
;
this
.
detectChanges
();
},
1
);
if
(
!
this
.
maxHeightAllowed
)
{
this
.
maxHeightAllowed
=
320
;
}
setTimeout
(()
=>
{
this
.
realHeight
=
this
.
_element
.
clientHeight
;
if
(
this
.
button
&&
!
this
.
button
.
content
)
{
this
.
button
.
content
=
this
;
}
if
(
this
.
realHeight
>
this
.
maxHeightAllowed
)
{
this
.
_element
.
style
.
maxHeight
=
this
.
maxHeightAllowed
+
'
px
'
;
this
.
_element
.
style
.
position
=
'
relative
'
;
setTimeout
(()
=>
{
this
.
expandable
=
true
;
this
.
detectChanges
();
},
1
);
}
},
1
);
}
expand
()
{
...
...
src/app/modules/blockchain/marketing/marketing.component.scss
View file @
13c6f471
...
...
@@ -155,7 +155,7 @@ m-blockchain--marketing {
m-video
.minds-video-play-icon
{
@include
m-theme
(){
text-shadow
:
0
0
3px
themed
(
$m-
grey-900
);
text-shadow
:
0
0
3px
rgba
(
themed
(
$m-
black-always
)
,
0
.6
);
}
}
...
...
src/app/modules/blogs/view/view.html
View file @
13c6f471
...
...
@@ -13,7 +13,7 @@
<div
class=
"m-mature-overlay"
(click)=
"blog.mature_visibility = !blog.mature_visibility"
>
<span
class=
"m-mature-overlay-note"
>
<i
class=
"material-icons"
title=
"Mature content"
i18n-title=
"@@M__COMMON__MATURE_CONTENT"
>
explicit
</i>
<span
i18n=
"@@M__COMMON__CONFIRM_18"
>
Click to confirm you
r
are 18+
</span>
<span
i18n=
"@@M__COMMON__CONFIRM_18"
>
Click to confirm you are 18+
</span>
</span>
</div>
<minds-banner
[src]=
"blog.thumbnail_src"
[object]=
"blog"
*ngIf=
"blog.header_bg"
></minds-banner>
...
...
src/app/modules/comments/card/comment.component.scss
View file @
13c6f471
...
...
@@ -101,6 +101,12 @@
}
}
&
.selected
:hover
{
@include
m-theme
(){
color
:
themed
(
$m-blue-dark
)
!
important
;
}
}
span
{
vertical-align
:
middle
;
line-height
:
16px
;
...
...
src/app/modules/comments/comment/comment.component.scss
View file @
13c6f471
...
...
@@ -33,7 +33,7 @@
>
a
{
display
:
block
;
height
:
16px
;
height
:
16px
;
line-height
:
16px
;
font-size
:
13px
;
font-weight
:
600
;
...
...
@@ -104,6 +104,12 @@
}
}
&
.selected
:hover
{
@include
m-theme
(){
color
:
themed
(
$m-blue-dark
)
!
important
;
}
}
span
{
vertical-align
:
middle
;
line-height
:
16px
;
...
...
src/app/modules/comments/comments.component.scss
View file @
13c6f471
...
...
@@ -10,5 +10,16 @@
}
}
}
.m-comments-composer--overflow
{
position
:
absolute
;
top
:
0
;
right
:
0
;
bottom
:
0
;
width
:
100px
;
height
:
24px
;
@include
m-theme
(){
background
:
linear-gradient
(
to
right
,
rgba
(
themed
(
$m-white-always
)
,
0
)
0%
,
rgba
(
themed
(
$m-white
)
,
1
)
25%
);
}
}
}
\ No newline at end of file
src/app/modules/comments/list/list.component.html
View file @
13c6f471
...
...
@@ -23,7 +23,7 @@
<span
*ngIf=
"!descendingInProgress && loaded"
>
<i
class=
"material-icons"
>
update
</i>
<ng-container
i18n=
"@@MINDS__COMMENTS__LOAD_EARLIER_ACTION"
>
Load earlier
</ng-container>
</span>
</div>
<p
class=
"m-comments--start-conversation-label"
...
...
@@ -100,6 +100,8 @@
</div>
<div
class=
"mdl-card__actions"
>
<!-- Overflow -->
<div
class=
"m-comments-composer--overflow"
></div>
<!-- Attachements -->
<div
class=
"attachment-button"
[ngClass]=
"{ 'mdl-color-text--amber-500': attachment.hasFile() }"
>
<i
class=
"material-icons"
>
attachment
</i>
...
...
src/app/modules/comments/poster/poster.component.html
View file @
13c6f471
...
...
@@ -39,8 +39,9 @@
</div>
<div
class=
"mdl-card__actions"
>
<!-- Overflow -->
<div
class=
"m-comments-composer--overflow"
></div>
<!-- Attachements -->
<div
class=
"attachment-button"
[ngClass]=
"{ 'mdl-color-text--amber-500': attachment.hasFile() }"
>
<i
class=
"material-icons"
>
attachment
</i>
<input
type=
"file"
id=
"file"
#file
name=
"attachment"
(change)=
"uploadAttachment(file, $event)"
/>
...
...
src/app/modules/hashtags/sidebar-selector/sidebar-selector.component.scss
View file @
13c6f471
...
...
@@ -218,7 +218,7 @@ m-hashtags--sidebar-selector {
width
:
48px
;
z-index
:
1
;
@include
m-theme
(){
background
:
linear-gradient
(
to
right
,
transparent
0%
,
rgba
(
themed
(
$m-body-bg
)
,
1
)
50%
);
background
:
linear-gradient
(
to
right
,
rgba
(
themed
(
$m-white-always
)
,
0
)
0%
,
rgba
(
themed
(
$m-body-bg
)
,
1
)
50%
);
}
.m-hashtagsSidebarSelectorCompactListOverflow__Arrow
{
...
...
src/app/modules/legacy/components/cards/activity/activity.component.scss
View file @
13c6f471
...
...
@@ -31,6 +31,12 @@ minds-activity {
}
}
.m-activity--image-link
{
&
:hover
{
cursor
:
pointer
;
}
}
m-safe-toggle
{
.m-safe-toggle
{
display
:
inline-block
;
...
...
src/app/modules/legacy/components/cards/activity/activity.html
View file @
13c6f471
...
...
@@ -153,6 +153,7 @@
<button
class=
"mdl-button mdl-button--colored mdl-button--raised"
(click)=
"activity.title = titleEdit.value; save();"
i18n=
"@@M__ACTION__SAVE"
>
Save
</button>
</div>
<!-- Video -->
<div
class=
"item item-image item-image-video m-activity--video"
[ngClass]=
"{ 'm-mature-content': attachment.shouldBeBlurred(activity), 'm-mature-content-shown': attachment.isForcefullyShown(activity) }"
*ngIf=
"activity.custom_type == 'video'"
>
...
...
@@ -172,6 +173,9 @@
[guid]=
"activity.custom_data.guid"
[playCount]=
"activity['play:count']"
[torrent]=
"[{ res: '360', key: activity.custom_data.guid + '/360.mp4' }]"
[isActivity]=
"true"
(videoMetadataLoaded)=
"setVideoDimensions($event)"
(mediaModalRequested)=
"showMediaModal()"
#player
>
<video-ads
[player]=
"player"
*ngIf=
"activity.monetized"
></video-ads>
</m-video>
...
...
@@ -188,7 +192,7 @@
</span>
</div>
<a
[routerLink]=
"['/media', activity.entity_guid]
"
>
<a
class=
"m-activity--image-link
"
>
<img
[src]=
"activity.thumbnail_src"
(error)=
"activity.thumbnail_src = null"
>
</a>
</div>
...
...
@@ -203,11 +207,13 @@
<span
i18n=
"@@M__COMMON__CONFIRM_18"
>
Click to confirm your are 18+
</span>
</span>
</div>
<a
[routerLink]=
"['/media', activity.entity_guid]"
>
<img
[src]=
"activity.custom_data[0].src"
style=
"width:100%"
(error)=
"activity.custom_data[0].src = minds.cdn_assets_url + 'assets/logos/placeholder-bulb.jpg'"
<a
class=
"m-activity--image-link"
>
<img
[src]=
"activity.custom_data[0].src"
style=
"width:100%"
(error)=
"activity.custom_data[0].src = minds.cdn_assets_url + 'assets/logos/placeholder-bulb.jpg'"
*ngIf=
"activity.custom_data"
(click)=
"showMediaModal()"
#batchImage
>
</a>
</div>
...
...
@@ -219,6 +225,7 @@
[events]=
"childEventsEmitter"
[boosted]=
"activity.boosted"
(matureVisibilityChange)=
"onRemindMatureVisibilityChange()"
(videoMetadataLoaded)=
"setVideoDimensions($event)"
></minds-remind>
</ng-container>
<ng-template
#blockedRemindTemplate
>
...
...
@@ -233,6 +240,7 @@
<ng-content
select=
"[bottom-content]"
></ng-content>
<!-- Action buttons -->
<div
class=
"tabs"
*ngIf=
"!hideTabs && !isPending(activity)"
>
<minds-button-thumbs-up
[object]=
"activity"
></minds-button-thumbs-up>
<minds-button-thumbs-down
[object]=
"activity"
></minds-button-thumbs-down>
...
...
@@ -249,7 +257,7 @@
<ng-container
i18n=
"verb|@@M__ACTION__BOOST"
>
Boost
</ng-container>
</a>
</div>
<!-- Activity metrics -->
<div
class=
"impressions-tag m-activity--metrics"
[class.m-activity--metrics-wire]=
"!session.getLoggedInUser() || session.getLoggedInUser().guid != activity.owner_guid"
*ngIf=
"!activity.hide_impressions && !hideTabs"
>
<div
class=
"m-activity--metrics-inner m-border"
>
<div
class=
"m-activity--metrics-metric"
(click)=
"showWire()"
>
...
...
src/app/modules/legacy/components/cards/activity/activity.ts
View file @
13c6f471
...
...
@@ -16,6 +16,7 @@ import { Session } from '../../../../../services/session';
import
{
AttachmentService
}
from
'
../../../../../services/attachment
'
;
import
{
TranslationService
}
from
'
../../../../../services/translation
'
;
import
{
OverlayModalService
}
from
'
../../../../../services/ux/overlay-modal
'
;
import
{
MediaModalComponent
}
from
'
../../../../media/modal/modal.component
'
;
import
{
BoostCreatorComponent
}
from
'
../../../../boost/creator/creator.component
'
;
import
{
WireCreatorComponent
}
from
'
../../../../wire/creator/creator.component
'
;
import
{
MindsVideoComponent
}
from
'
../../../../media/components/video/video.component
'
;
...
...
@@ -26,6 +27,8 @@ import { ActivityAnalyticsOnViewService } from "./activity-analytics-on-view.ser
import
{
NewsfeedService
}
from
"
../../../../newsfeed/services/newsfeed.service
"
;
import
{
ClientMetaService
}
from
"
../../../../../common/services/client-meta.service
"
;
import
{
AutocompleteSuggestionsService
}
from
"
../../../../suggestions/services/autocomplete-suggestions.service
"
;
import
{
FeaturesService
}
from
'
../../../../../services/features.service
'
;
import
isMobile
from
'
../../../../../helpers/is-mobile
'
;
@
Component
({
moduleId
:
module
.
id
,
...
...
@@ -87,6 +90,8 @@ export class Activity implements OnInit {
blockedUsers
:
string
[]
=
[];
videoDimensions
:
Array
<
any
>
=
null
;
get
menuOptions
():
Array
<
string
>
{
if
(
!
this
.
activity
||
!
this
.
activity
.
ephemeral
)
{
if
(
this
.
showBoostMenuOptions
)
{
...
...
@@ -100,6 +105,7 @@ export class Activity implements OnInit {
}
@
ViewChild
(
'
player
'
,
{
static
:
false
})
player
:
MindsVideoComponent
;
@
ViewChild
(
'
batchImage
'
,
{
static
:
false
})
batchImage
:
ElementRef
;
constructor
(
public
session
:
Session
,
...
...
@@ -114,6 +120,7 @@ export class Activity implements OnInit {
protected
activityAnalyticsOnViewService
:
ActivityAnalyticsOnViewService
,
protected
newsfeedService
:
NewsfeedService
,
protected
clientMetaService
:
ClientMetaService
,
protected
featuresService
:
FeaturesService
,
public
suggestions
:
AutocompleteSuggestionsService
,
@
SkipSelf
()
injector
:
Injector
,
elementRef
:
ElementRef
,
...
...
@@ -149,7 +156,7 @@ export class Activity implements OnInit {
this
.
activityAnalyticsOnViewService
.
setEntity
(
this
.
activity
);
if
(
this
.
activity
.
custom_type
==
'
batch
'
this
.
activity
.
custom_type
==
=
'
batch
'
&&
this
.
activity
.
custom_data
&&
this
.
activity
.
custom_data
[
0
].
src
)
{
...
...
@@ -432,6 +439,42 @@ export class Activity implements OnInit {
this
.
activity
.
mature_visibility
=
!
this
.
activity
.
mature_visibility
;
}
setVideoDimensions
(
$event
)
{
this
.
videoDimensions
=
$event
.
dimensions
;
}
setImageDimensions
()
{
const
img
:
HTMLImageElement
=
this
.
batchImage
.
nativeElement
;
this
.
activity
.
custom_data
[
0
].
width
=
img
.
naturalWidth
;
this
.
activity
.
custom_data
[
0
].
height
=
img
.
naturalHeight
;
}
showMediaModal
()
{
if
(
this
.
featuresService
.
has
(
'
media-modal
'
))
{
// Mobile (not tablet) users go to media page instead of modal
if
(
isMobile
()
&&
Math
.
min
(
screen
.
width
,
screen
.
height
)
<
768
)
{
this
.
router
.
navigate
([
`/media/
${
this
.
activity
.
entity_guid
}
`
]);
}
if
(
this
.
activity
.
custom_type
===
'
video
'
)
{
this
.
activity
.
custom_data
.
dimensions
=
this
.
videoDimensions
;
}
else
{
// Image
// Set image dimensions if they're not already there
if
(
this
.
activity
.
custom_data
[
0
].
width
===
'
0
'
||
this
.
activity
.
custom_data
[
0
].
height
===
'
0
'
)
{
this
.
setImageDimensions
();
}
}
this
.
activity
.
modal_source_url
=
this
.
router
.
url
;
this
.
overlayModal
.
create
(
MediaModalComponent
,
this
.
activity
,
{
class
:
'
m-overlayModal--media
'
}).
present
();
}
else
{
this
.
router
.
navigate
([
`/media/
${
this
.
activity
.
entity_guid
}
`
]);
}
}
detectChanges
()
{
this
.
cd
.
markForCheck
();
this
.
cd
.
detectChanges
();
...
...
src/app/modules/legacy/components/cards/cards.scss
View file @
13c6f471
...
...
@@ -74,7 +74,7 @@ minds-card-user, .minds-banner-card{
text-overflow
:
ellipsis
;
font-size
:
16px
;
line-height
:
18px
;
padding
:
0
;
padding
:
0
0
0
1px
;
margin
:
0
;
@include
m-theme
(){
text-shadow
:
-1px
-1px
0
themed
(
$m-black-always
)
,
1px
-1px
0
themed
(
$m-black-always
)
,
-1px
1px
0
themed
(
$m-black-always
)
,
1px
1px
0
themed
(
$m-black-always
);
...
...
@@ -85,6 +85,7 @@ minds-card-user, .minds-banner-card{
overflow
:
hidden
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
padding
:
0
0
0
1px
;
@include
m-theme
(){
text-shadow
:
-1px
-1px
0
themed
(
$m-black-always
)
,
1px
-1px
0
themed
(
$m-black-always
)
,
-1px
1px
0
themed
(
$m-black-always
)
,
1px
1px
0
themed
(
$m-black-always
);
}
...
...
@@ -305,7 +306,7 @@ minds-activity.mdl-card, minds-activity, minds-activity-preview{
.m-owner-block--remind
{
overflow
:
visible
;
i
{
font-size
:
18px
;
margin-right
:
12px
;
...
...
@@ -564,7 +565,7 @@ minds-activity.mdl-card, minds-activity, minds-activity-preview{
@include
m-theme
(){
color
:
themed
(
$m-blue
)
!
important
;
}
&
:hover
{
@include
m-theme
(){
color
:
rgba
(
themed
(
$m-blue-dark
)
,
0
.9
)
!
important
;
...
...
src/app/modules/legacy/components/cards/remind/remind.ts
View file @
13c6f471
import
{
Component
,
ChangeDetectionStrategy
,
ChangeDetectorRef
,
EventEmitter
,
Input
,
Output
}
from
'
@angular/core
'
;
import
{
Component
,
ChangeDetectionStrategy
,
ChangeDetectorRef
,
EventEmitter
,
Input
,
Output
,
ViewChild
,
ElementRef
,
}
from
'
@angular/core
'
;
import
{
Router
}
from
"
@angular/router
"
;
import
{
Client
}
from
'
../../../../../services/api
'
;
import
{
Session
}
from
'
../../../../../services/session
'
;
import
{
AttachmentService
}
from
'
../../../../../services/attachment
'
;
import
{
OverlayModalService
}
from
'
../../../../../services/ux/overlay-modal
'
;
import
{
MediaModalComponent
}
from
'
../../../../media/modal/modal.component
'
;
import
{
FeaturesService
}
from
'
../../../../../services/features.service
'
;
import
isMobile
from
'
../../../../../helpers/is-mobile
'
;
@
Component
({
moduleId
:
module
.
id
,
...
...
@@ -32,14 +47,20 @@ export class Remind {
isTranslatable
:
boolean
=
false
;
menuOptions
:
any
=
[];
canDelete
:
boolean
=
false
;
videoDimensions
:
Array
<
any
>
=
null
;
@
Output
(
'
matureVisibilityChange
'
)
onMatureVisibilityChange
:
EventEmitter
<
any
>
=
new
EventEmitter
<
any
>
();
@
ViewChild
(
'
batchImage
'
,
{
static
:
false
})
batchImage
:
ElementRef
;
constructor
(
public
session
:
Session
,
public
client
:
Client
,
public
attachment
:
AttachmentService
,
private
changeDetectorRef
:
ChangeDetectorRef
private
changeDetectorRef
:
ChangeDetectorRef
,
private
overlayModal
:
OverlayModalService
,
private
router
:
Router
,
protected
featuresService
:
FeaturesService
,
)
{
this
.
hideTabs
=
true
;
}
...
...
@@ -67,8 +88,8 @@ export class Remind {
this
.
activity
.
boosted
=
this
.
boosted
;
if
(
this
.
activity
.
custom_type
==
'
batch
'
&&
this
.
activity
.
custom_data
this
.
activity
.
custom_type
==
'
batch
'
&&
this
.
activity
.
custom_data
&&
this
.
activity
.
custom_data
[
0
].
src
)
{
this
.
activity
.
custom_data
[
0
].
src
=
this
.
activity
.
custom_data
[
0
].
src
.
replace
(
this
.
minds
.
site_url
,
this
.
minds
.
cdn_url
);
...
...
@@ -127,4 +148,40 @@ export class Remind {
this
.
onMatureVisibilityChange
.
emit
();
}
setVideoDimensions
(
$event
)
{
this
.
videoDimensions
=
$event
.
dimensions
;
}
setImageDimensions
()
{
const
img
:
HTMLImageElement
=
this
.
batchImage
.
nativeElement
;
this
.
activity
.
custom_data
[
0
].
width
=
img
.
naturalWidth
;
this
.
activity
.
custom_data
[
0
].
height
=
img
.
naturalHeight
;
}
showMediaModal
()
{
if
(
this
.
featuresService
.
has
(
'
media-modal
'
))
{
// Mobile (not tablet) users go to media page instead of modal
if
(
isMobile
()
&&
Math
.
min
(
screen
.
width
,
screen
.
height
)
<
768
)
{
this
.
router
.
navigate
([
`/media/
${
this
.
activity
.
entity_guid
}
`
]);
}
if
(
this
.
activity
.
custom_type
===
'
video
'
)
{
this
.
activity
.
custom_data
.
dimensions
=
this
.
videoDimensions
;
}
else
{
// Image
// Set image dimensions if they're not already there
if
(
this
.
activity
.
custom_data
[
0
].
width
===
'
0
'
||
this
.
activity
.
custom_data
[
0
].
height
===
'
0
'
)
{
this
.
setImageDimensions
();
}
}
this
.
activity
.
modal_source_url
=
this
.
router
.
url
;
this
.
overlayModal
.
create
(
MediaModalComponent
,
this
.
activity
,
{
class
:
'
m-overlayModal--media
'
}).
present
();
}
else
{
this
.
router
.
navigate
([
`/media/
${
this
.
activity
.
entity_guid
}
`
]);
}
}
}
src/app/modules/media/components/video/players/direct-http.component.html
View file @
13c6f471
<video
[src]=
"src"
(click)=
"toggle()"
[autoplay]=
"autoplay"
[poster]=
"poster"
[muted]=
"muted"
...
...
src/app/modules/media/components/video/players/direct-http.component.ts
View file @
13c6f471
...
...
@@ -16,6 +16,7 @@ export class MindsVideoDirectHttpPlayer implements OnInit, OnDestroy, MindsPlaye
@
Input
()
muted
:
boolean
=
false
;
@
Input
()
poster
:
string
=
''
;
@
Input
()
autoplay
:
boolean
=
false
;
@
Input
()
guid
:
string
|
number
;
src
:
string
;
@
Input
(
'
src
'
)
set
_src
(
src
:
string
)
{
...
...
@@ -35,25 +36,26 @@ export class MindsVideoDirectHttpPlayer implements OnInit, OnDestroy, MindsPlaye
@
Output
()
onPause
:
EventEmitter
<
HTMLVideoElement
>
=
new
EventEmitter
();
@
Output
()
onEnd
:
EventEmitter
<
HTMLVideoElement
>
=
new
EventEmitter
();
@
Output
()
onError
:
EventEmitter
<
{
player
:
HTMLVideoElement
,
e
}
>
=
new
EventEmitter
();
@
Output
()
onCanPlayThrough
:
EventEmitter
<
any
>
=
new
EventEmitter
();
@
Output
()
onLoadedMetadata
:
EventEmitter
<
any
>
=
new
EventEmitter
();
loading
:
boolean
=
false
;
constructor
(
protected
cd
:
ChangeDetectorRef
protected
cd
:
ChangeDetectorRef
,
)
{
}
protected
_emitPlay
=
()
=>
this
.
onPlay
.
emit
(
this
.
getPlayer
());
protected
_emitPause
=
()
=>
this
.
onPause
.
emit
(
this
.
getPlayer
());
protected
_emitEnd
=
()
=>
this
.
onEnd
.
emit
(
this
.
getPlayer
());
protected
_emitError
=
e
=>
this
.
onError
.
emit
({
player
:
this
.
getPlayer
(),
e
});
protected
_emitCanPlayThrough
=
()
=>
this
.
onCanPlayThrough
.
emit
(
this
.
getPlayer
());
protected
_emitLoadedMetadata
=
()
=>
this
.
onLoadedMetadata
.
emit
(
this
.
getPlayer
());
protected
_canPlayThrough
=
()
=>
{
this
.
loading
=
false
;
this
.
detectChanges
();
};
protected
_dblClick
=
()
=>
{
this
.
requestFullScreen
();
this
.
_emitCanPlayThrough
();
};
protected
_onPlayerError
=
e
=>
{
...
...
@@ -70,12 +72,12 @@ export class MindsVideoDirectHttpPlayer implements OnInit, OnDestroy, MindsPlaye
ngOnInit
()
{
const
player
=
this
.
getPlayer
();
player
.
addEventListener
(
'
dblclick
'
,
this
.
_dblClick
);
player
.
addEventListener
(
'
playing
'
,
this
.
_emitPlay
);
player
.
addEventListener
(
'
pause
'
,
this
.
_emitPause
);
player
.
addEventListener
(
'
ended
'
,
this
.
_emitEnd
);
player
.
addEventListener
(
'
error
'
,
this
.
_onPlayerError
);
player
.
addEventListener
(
'
canplaythrough
'
,
this
.
_canPlayThrough
);
player
.
addEventListener
(
'
loadedmetadata
'
,
this
.
_emitLoadedMetadata
);
this
.
loading
=
true
;
}
...
...
@@ -84,12 +86,12 @@ export class MindsVideoDirectHttpPlayer implements OnInit, OnDestroy, MindsPlaye
const
player
=
this
.
getPlayer
();
if
(
player
)
{
player
.
removeEventListener
(
'
dblclick
'
,
this
.
_dblClick
);
player
.
removeEventListener
(
'
playing
'
,
this
.
_emitPlay
);
player
.
removeEventListener
(
'
pause
'
,
this
.
_emitPause
);
player
.
removeEventListener
(
'
ended
'
,
this
.
_emitEnd
);
player
.
removeEventListener
(
'
error
'
,
this
.
_onPlayerError
);
player
.
removeEventListener
(
'
canplaythrough
'
,
this
.
_canPlayThrough
);
player
.
removeEventListener
(
'
loadedmetadata
'
,
this
.
_emitLoadedMetadata
);
}
}
...
...
@@ -170,4 +172,5 @@ export class MindsVideoDirectHttpPlayer implements OnInit, OnDestroy, MindsPlaye
this
.
cd
.
markForCheck
();
this
.
cd
.
detectChanges
();
}
}
src/app/modules/media/components/video/players/torrent.component.html
View file @
13c6f471
<video
(click)=
"toggle()"
[poster]=
"poster"
[muted]=
"muted"
preload=
"none"
...
...
src/app/modules/media/components/video/players/torrent.component.ts
View file @
13c6f471
...
...
@@ -20,6 +20,7 @@ export class MindsVideoTorrentPlayer implements OnInit, AfterViewInit, OnDestroy
@
Input
()
muted
:
boolean
=
false
;
@
Input
()
poster
:
string
=
''
;
@
Input
()
autoplay
:
boolean
=
false
;
@
Input
()
guid
:
string
|
number
;
src
:
string
;
@
Input
(
'
src
'
)
set
_src
(
src
:
string
)
{
...
...
@@ -38,9 +39,12 @@ export class MindsVideoTorrentPlayer implements OnInit, AfterViewInit, OnDestroy
@
Output
()
onPause
:
EventEmitter
<
HTMLVideoElement
>
=
new
EventEmitter
();
@
Output
()
onEnd
:
EventEmitter
<
HTMLVideoElement
>
=
new
EventEmitter
();
@
Output
()
onError
:
EventEmitter
<
{
player
,
e
}
>
=
new
EventEmitter
();
@
Output
()
onCanPlayThrough
:
EventEmitter
<
any
>
=
new
EventEmitter
();
@
Output
()
onLoadedMetadata
:
EventEmitter
<
any
>
=
new
EventEmitter
();
initialized
:
boolean
=
false
;
loading
:
boolean
=
false
;
isModal
:
boolean
=
false
;
protected
torrentId
:
string
;
protected
torrentReady
:
boolean
=
false
;
...
...
@@ -67,10 +71,13 @@ export class MindsVideoTorrentPlayer implements OnInit, AfterViewInit, OnDestroy
protected
_emitPause
=
()
=>
this
.
onPause
.
emit
(
this
.
getPlayer
());
protected
_emitEnd
=
()
=>
this
.
onEnd
.
emit
(
this
.
getPlayer
());
protected
_emitError
=
e
=>
this
.
onError
.
emit
({
player
:
this
.
getPlayer
(),
e
});
protected
_emitCanPlayThrough
=
()
=>
this
.
onCanPlayThrough
.
emit
(
this
.
getPlayer
());
protected
_emitLoadedMetadata
=
()
=>
this
.
onLoadedMetadata
.
emit
(
this
.
getPlayer
());
protected
_canPlayThrough
=
()
=>
{
this
.
loading
=
false
;
this
.
detectChanges
();
this
.
_emitCanPlayThrough
();
};
protected
_dblClick
=
()
=>
{
...
...
@@ -130,8 +137,10 @@ export class MindsVideoTorrentPlayer implements OnInit, AfterViewInit, OnDestroy
player
.
addEventListener
(
'
ended
'
,
this
.
_emitEnd
);
player
.
addEventListener
(
'
error
'
,
this
.
_onPlayerError
);
player
.
addEventListener
(
'
canplaythrough
'
,
this
.
_canPlayThrough
);
player
.
addEventListener
(
'
loadedmetadata
'
,
this
.
_emitLoadedMetadata
);
this
.
infoTimer$
=
setInterval
(
this
.
_refreshInfo
,
1000
);
this
.
isModal
=
document
.
body
.
classList
.
contains
(
'
m-overlay-modal--shown
'
);
}
ngAfterViewInit
()
{
...
...
@@ -158,6 +167,7 @@ export class MindsVideoTorrentPlayer implements OnInit, AfterViewInit, OnDestroy
player
.
removeEventListener
(
'
ended
'
,
this
.
_emitEnd
);
player
.
removeEventListener
(
'
error
'
,
this
.
_onPlayerError
);
player
.
removeEventListener
(
'
canplaythrough
'
,
this
.
_canPlayThrough
);
player
.
removeEventListener
(
'
loadedmetadata
'
,
this
.
_emitLoadedMetadata
);
}
}
...
...
@@ -353,4 +363,5 @@ export class MindsVideoTorrentPlayer implements OnInit, AfterViewInit, OnDestroy
this
.
torrentReady
=
false
;
}
}
}
src/app/modules/media/components/video/progress-bar/progress-bar.component.spec.ts
View file @
13c6f471
...
...
@@ -53,7 +53,7 @@ describe('MindsVideoProgressBar', () => {
TestBed
.
configureTestingModule
({
declarations
:
[
MindsVideoProgressBar
],
// declare the test component
imports
:
[
imports
:
[
FormsModule
,
RouterTestingModule
,
NgCommonModule
],
...
...
@@ -98,14 +98,14 @@ describe('MindsVideoProgressBar', () => {
jasmine
.
clock
().
uninstall
();
});
it
(
'
should have a Play icon and a Control bar
'
,
()
=>
{
const
seeker
=
fixture
.
debugElement
.
query
(
By
.
css
(
'
#seeker
'
));
const
seekerBall
=
fixture
.
debugElement
.
query
(
By
.
css
(
'
.seeker-ball
'
));
const
stamps
=
fixture
.
debugElement
.
query
(
By
.
css
(
'
.progress-stamps
'
));
expect
(
seeker
).
not
.
toBeNull
();
expect
(
seekerBall
).
not
.
toBeNull
();
expect
(
stamps
).
not
.
toBeNull
();
});
//
it('should have a Play icon and a Control bar', () => {
//
const seeker = fixture.debugElement.query(By.css('#seeker'));
//
const seekerBall = fixture.debugElement.query(By.css('.seeker-ball'));
//
const stamps = fixture.debugElement.query(By.css('.progress-stamps'));
//
expect(seeker).not.toBeNull();
//
expect(seekerBall).not.toBeNull();
//
expect(stamps).not.toBeNull();
//
});
it
(
'
time is properly calculated
'
,
()
=>
{
comp
.
duration
=
111
;
...
...
@@ -212,5 +212,5 @@ describe('MindsVideoProgressBar', () => {
fixture
.
detectChanges
();
expect
(
comp
.
elapsed
).
toEqual
({
minutes
:
'
00
'
,
seconds
:
11
});
});
});
Prev
1
2
Next