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)
(fix): Scroll visibility debounce (
#1266
)
· a890aeb8
Emiliano Balbuena
authored
May 30, 2019
and
Mark Harding
committed
May 30, 2019
a890aeb8
Merge branch 'hotfix/activities.view.debounce' into 'master'
· 38c2fee7
Mark Harding
authored
May 30, 2019
(fix): Scroll visibility debounce (
#1266
) See merge request
!286
38c2fee7
Hide whitespace changes
Inline
Side-by-side
src/app/modules/legacy/components/cards/activity/activity-analytics-on-view.service.ts
0 → 100644
View file @
38c2fee7
import
{
ElementRef
,
Injectable
,
OnDestroy
}
from
"
@angular/core
"
;
import
{
debounceTime
}
from
"
rxjs/operators
"
;
import
{
Subject
,
Subscription
}
from
"
rxjs
"
;
import
{
ScrollService
}
from
"
../../../../../services/ux/scroll
"
;
import
{
NewsfeedService
}
from
"
../../../../newsfeed/services/newsfeed.service
"
;
@
Injectable
()
export
class
ActivityAnalyticsOnViewService
implements
OnDestroy
{
protected
element
:
HTMLElement
;
protected
entity
;
protected
visibility$
:
Subscription
;
protected
visibilitySubject
:
Subject
<
boolean
>
=
new
Subject
();
protected
scroll$
:
Subscription
;
protected
visible
:
boolean
=
false
;
protected
onViewFn
:
()
=>
void
;
protected
enabled
:
boolean
=
true
;
constructor
(
protected
scroll
:
ScrollService
,
protected
newsfeedService
:
NewsfeedService
,
)
{
this
.
init
();
}
setElementRef
(
elementRef
:
ElementRef
|
null
)
{
this
.
element
=
(
elementRef
&&
elementRef
.
nativeElement
)
||
void
0
;
return
this
;
}
setEntity
(
entity
)
{
this
.
entity
=
entity
||
void
0
;
return
this
;
}
onView
(
fn
:
()
=>
void
)
{
this
.
onViewFn
=
fn
;
return
this
;
}
setEnabled
(
enabled
:
boolean
)
{
this
.
enabled
=
enabled
;
return
this
;
}
init
()
{
this
.
visibility$
=
this
.
visibilitySubject
.
pipe
(
debounceTime
(
300
))
.
subscribe
(()
=>
{
if
(
this
.
entity
&&
this
.
visible
)
{
this
.
scroll
.
unListen
(
this
.
scroll$
);
this
.
newsfeedService
.
recordView
(
this
.
entity
);
if
(
this
.
onViewFn
)
{
this
.
onViewFn
();
}
}
});
this
.
scroll$
=
this
.
scroll
.
listenForView
()
.
subscribe
(()
=>
{
if
(
!
this
.
element
)
{
console
.
warn
(
'
Missing element ref
'
);
return
;
}
if
(
!
this
.
element
.
offsetHeight
||
!
this
.
enabled
)
{
return
;
}
const
top
=
this
.
element
.
offsetTop
;
const
bottom
=
top
+
this
.
element
.
offsetHeight
;
const
vpTop
=
this
.
scroll
.
view
.
scrollTop
;
const
vpBottom
=
vpTop
+
this
.
scroll
.
view
.
clientHeight
;
const
totalH
=
Math
.
max
(
bottom
,
vpBottom
)
-
Math
.
min
(
top
,
vpTop
);
const
vpComp
=
totalH
-
this
.
scroll
.
view
.
clientHeight
;
const
vpEl
=
this
.
element
.
offsetHeight
-
vpComp
;
const
visible
=
vpEl
<=
0
?
0
:
(
vpEl
/
this
.
element
.
offsetHeight
);
if
(
visible
>
0
&&
!
this
.
visible
)
{
this
.
visible
=
true
;
this
.
visibilitySubject
.
next
(
this
.
visible
);
}
else
{
this
.
visible
=
false
;
}
});
}
ngOnDestroy
()
{
this
.
scroll
.
unListen
(
this
.
scroll$
);
if
(
this
.
visibility$
)
{
this
.
visibility$
.
unsubscribe
();
}
}
}
src/app/modules/legacy/components/cards/activity/activity.ts
View file @
38c2fee7
import
{
Component
,
ChangeDetectionStrategy
,
ChangeDetectorRef
,
EventEmitter
,
ElementRef
,
Input
,
ViewChild
}
from
'
@angular/core
'
;
import
{
Component
,
ChangeDetectionStrategy
,
ChangeDetectorRef
,
EventEmitter
,
ElementRef
,
Input
,
ViewChild
,
OnInit
}
from
'
@angular/core
'
;
import
{
Client
}
from
'
../../../../../services/api
'
;
import
{
Session
}
from
'
../../../../../services/session
'
;
import
{
ScrollService
}
from
'
../../../../../services/ux/scroll
'
;
import
{
AttachmentService
}
from
'
../../../../../services/attachment
'
;
import
{
TranslationService
}
from
'
../../../../../services/translation
'
;
import
{
OverlayModalService
}
from
'
../../../../../services/ux/overlay-modal
'
;
import
{
BoostCreatorComponent
}
from
'
../../../../boost/creator/creator.component
'
;
import
{
WireCreatorComponent
}
from
'
../../../../wire/creator/creator.component
'
;
import
{
MindsVideoComponent
}
from
'
../../../../media/components/video/video.component
'
;
import
{
NewsfeedService
}
from
'
../../../../newsfeed/services/newsfeed.service
'
;
import
{
EntitiesService
}
from
"
../../../../../common/services/entities.service
"
;
import
{
Router
}
from
"
@angular/router
"
;
import
{
BlockListService
}
from
"
../../../../../common/services/block-list.service
"
;
import
{
ActivityAnalyticsOnViewService
}
from
"
./activity-analytics-on-view.service
"
;
@
Component
({
moduleId
:
module
.
id
,
...
...
@@ -22,11 +30,12 @@ import { BlockListService } from "../../../../../common/services/block-list.serv
},
inputs
:
[
'
object
'
,
'
commentsToggle
'
,
'
focusedCommentGuid
'
,
'
visible
'
,
'
canDelete
'
,
'
showRatingToggle
'
],
outputs
:
[
'
_delete: delete
'
,
'
commentsOpened
'
,
'
onViewed
'
],
providers
:
[
ActivityAnalyticsOnViewService
],
templateUrl
:
'
activity.html
'
,
changeDetection
:
ChangeDetectionStrategy
.
OnPush
,
})
export
class
Activity
{
export
class
Activity
implements
OnInit
{
minds
=
window
.
Minds
;
...
...
@@ -42,6 +51,16 @@ export class Activity {
@
Input
(
'
boost-toggle
'
)
@
Input
()
showBoostMenuOptions
:
boolean
=
false
;
visibilityEvents
:
boolean
=
true
;
@
Input
(
'
visibilityEvents
'
)
set
_visibilityEvents
(
visibilityEvents
:
boolean
)
{
this
.
visibilityEvents
=
visibilityEvents
;
if
(
this
.
activityAnalyticsOnViewService
)
{
this
.
activityAnalyticsOnViewService
.
setEnabled
(
this
.
visibilityEvents
);
}
}
type
:
string
;
element
:
any
;
visible
:
boolean
=
false
;
...
...
@@ -52,7 +71,6 @@ export class Activity {
_delete
:
EventEmitter
<
any
>
=
new
EventEmitter
();
commentsOpened
:
EventEmitter
<
any
>
=
new
EventEmitter
();
@
Input
()
focusedCommentGuid
:
string
;
scroll_listener
;
childEventsEmitter
:
EventEmitter
<
any
>
=
new
EventEmitter
();
onViewed
:
EventEmitter
<
{
activity
,
visible
}
>
=
new
EventEmitter
<
{
activity
,
visible
}
>
();
...
...
@@ -80,9 +98,6 @@ export class Activity {
constructor
(
public
session
:
Session
,
public
client
:
Client
,
public
scroll
:
ScrollService
,
public
newsfeedService
:
NewsfeedService
,
_element
:
ElementRef
,
public
attachment
:
AttachmentService
,
public
translationService
:
TranslationService
,
private
overlayModal
:
OverlayModalService
,
...
...
@@ -90,10 +105,21 @@ export class Activity {
private
entitiesService
:
EntitiesService
,
private
router
:
Router
,
protected
blockListService
:
BlockListService
,
protected
activityAnalyticsOnViewService
:
ActivityAnalyticsOnViewService
,
elementRef
:
ElementRef
,
)
{
this
.
activityAnalyticsOnViewService
.
setElementRef
(
elementRef
)
.
onView
(()
=>
{
this
.
onViewed
.
emit
({
activity
:
this
.
activity
,
visible
:
true
});
});
}
this
.
element
=
_element
.
nativeElement
;
this
.
isVisible
();
ngOnInit
()
{
this
.
activityAnalyticsOnViewService
.
setEnabled
(
this
.
visibilityEvents
);
this
.
loadBlockedUsers
();
}
set
object
(
value
:
any
)
{
...
...
@@ -102,6 +128,8 @@ export class Activity {
this
.
activity
=
value
;
this
.
activity
.
url
=
window
.
Minds
.
site_url
+
'
newsfeed/
'
+
value
.
guid
;
this
.
activityAnalyticsOnViewService
.
setEntity
(
this
.
activity
);
if
(
this
.
activity
.
custom_type
==
'
batch
'
&&
this
.
activity
.
custom_data
...
...
@@ -326,39 +354,10 @@ export class Activity {
this
.
attachment
.
setNSFW
(
reasons
);
}
private
viewed
:
boolean
=
false
;
isVisible
()
{
if
(
this
.
visible
)
{
this
.
onViewed
.
emit
({
activity
:
this
.
activity
,
visible
:
true
});
return
true
;
}
this
.
scroll_listener
=
this
.
scroll
.
listenForView
().
subscribe
((
view
)
=>
{
if
(
this
.
element
.
offsetTop
-
this
.
scroll
.
view
.
clientHeight
<=
this
.
scroll
.
view
.
scrollTop
&&
!
this
.
visible
)
{
//stop listening
this
.
scroll
.
unListen
(
this
.
scroll_listener
);
//make visible
this
.
visible
=
true
;
//this.onViewed.emit({activity: this.activity, visible: true});
//update the analytics
this
.
newsfeedService
.
recordView
(
this
.
activity
);
}
});
}
isUnlisted
()
{
return
this
.
activity
.
access_id
===
'
0
'
||
this
.
activity
.
access_id
===
0
;
}
ngOnInit
()
{
this
.
loadBlockedUsers
();
}
ngOnDestroy
()
{
this
.
scroll
.
unListen
(
this
.
scroll_listener
);
}
propagateTranslation
(
$event
)
{
if
(
this
.
activity
.
remind_object
&&
this
.
translationService
.
isTranslatable
(
this
.
activity
.
remind_object
))
{
this
.
childEventsEmitter
.
emit
({
...
...
src/app/modules/newsfeed/boost-rotator/boost-rotator.component.html
View file @
38c2fee7
...
...
@@ -30,6 +30,7 @@
visible=
"true"
[hidden]=
"i != currentPosition"
[showBoostMenuOptions]=
"true"
[visibilityEvents]=
"false"
#activities
></minds-activity>
</ng-container>