Commit 5b94c667 authored by Mark Harding's avatar Mark Harding

(feat): extend views to blogs media channels and modals

parent 3cec965f
No related merge requests found
Pipeline #85177851 waiting for delayed job with stages
in 88 minutes and 30 seconds
......@@ -2,6 +2,7 @@ import { Injectable, Injector } from '@angular/core';
import { Location } from '@angular/common';
import hashCode from '../../helpers/hash-code';
import { Session } from '../../services/session';
import { Client } from '../../services/api';
let uniqId = 0;
......@@ -23,7 +24,11 @@ export class ClientMetaService {
protected inherited: boolean = false;
constructor(protected location: Location, protected session: Session) {
constructor(
protected location: Location,
protected session: Session,
protected client: Client
) {
this.id = ++uniqId;
this.timestamp = Date.now();
......@@ -146,6 +151,12 @@ export class ClientMetaService {
};
}
async recordView(entity) {
await this.client.post('api/v2/analytics/views/entity/' + entity.guid, {
client_meta: this.build(),
});
}
protected checkInheritance() {
if (!this.inherited) {
console.warn(
......
......@@ -6,6 +6,8 @@ import {
OnDestroy,
OnInit,
ViewChild,
Injector,
SkipSelf,
} from '@angular/core';
import { Router } from '@angular/router';
......@@ -22,6 +24,7 @@ import { optimizedResize } from '../../../utils/optimized-resize';
import { OverlayModalService } from '../../../services/ux/overlay-modal';
import { ActivityService } from '../../../common/services/activity.service';
import { ShareModalComponent } from '../../../modules/modals/share/share';
import { ClientMetaService } from '../../../common/services/client-meta.service';
@Component({
moduleId: module.id,
......@@ -30,7 +33,7 @@ import { ShareModalComponent } from '../../../modules/modals/share/share';
class: 'm-blog',
},
templateUrl: 'view.html',
providers: [ActivityService],
providers: [ActivityService, ClientMetaService],
})
export class BlogView implements OnInit, OnDestroy {
minds;
......@@ -98,8 +101,15 @@ export class BlogView implements OnInit, OnDestroy {
public analyticsService: AnalyticsService,
protected activityService: ActivityService,
private cd: ChangeDetectorRef,
private overlayModal: OverlayModalService
private overlayModal: OverlayModalService,
private clientMetaService: ClientMetaService,
@SkipSelf() injector: Injector
) {
this.clientMetaService
.inherit(injector)
.setSource('single')
.setMedium('single');
this.minds = window.Minds;
this.element = _element.nativeElement;
optimizedResize.add(this.onResize.bind(this));
......@@ -108,6 +118,7 @@ export class BlogView implements OnInit, OnDestroy {
ngOnInit() {
this.isVisible();
this.context.set('object:blog');
this.clientMetaService.recordView(this.blog);
}
isVisible() {
......
......@@ -37,6 +37,8 @@ import { FeaturesService } from '../../services/features.service';
import { featuresServiceMock } from '../../../tests/features-service-mock.spec';
import { BlockListService } from '../../common/services/block-list.service';
import { ChannelMode } from '../../interfaces/entities';
import { ClientMetaService } from '../../common/services/client-meta.service';
import { clientMetaServiceMock } from '../../../tests/client-meta-service-mock.spec';
describe('ChannelComponent', () => {
let comp: ChannelComponent;
......@@ -105,6 +107,7 @@ describe('ChannelComponent', () => {
},
{ provide: FeaturesService, useValue: featuresServiceMock },
{ provide: BlockListService, useValue: MockService(BlockListService) },
{ provide: ClientMetaService, useValue: clientMetaServiceMock },
],
}).compileComponents(); // compile template and css
}));
......
import { Component, ViewChild } from '@angular/core';
import { Component, ViewChild, SkipSelf, Injector } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs';
......@@ -17,11 +17,13 @@ import { Observable } from 'rxjs';
import { DialogService } from '../../common/services/confirm-leave-dialog.service';
import { BlockListService } from '../../common/services/block-list.service';
import { ChannelSortedComponent } from './sorted/sorted.component';
import { ClientMetaService } from '../../common/services/client-meta.service';
@Component({
moduleId: module.id,
selector: 'm-channel',
templateUrl: 'channel.component.html',
providers: [ClientMetaService],
})
export class ChannelComponent {
minds = window.Minds;
......@@ -53,8 +55,15 @@ export class ChannelComponent {
private recent: RecentService,
private context: ContextService,
private dialogService: DialogService,
private blockListService: BlockListService
) {}
private blockListService: BlockListService,
private clientMetaService: ClientMetaService,
@SkipSelf() injector: Injector
) {
this.clientMetaService
.inherit(injector)
.setSource('single')
.setMedium('single');
}
ngOnInit() {
this.title.setTitle('Channel');
......@@ -132,6 +141,8 @@ export class ChannelComponent {
if (this.session.getLoggedInUser()) {
this.addRecent();
}
this.clientMetaService.recordView(this.user);
})
.catch(e => {
if (e.status === 0) {
......
......@@ -62,33 +62,37 @@ export class ActivityAnalyticsOnViewService implements OnDestroy {
});
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;
}
this.checkVisibility();
});
}
checkVisibility() {
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$);
......
......@@ -239,6 +239,8 @@ export class Activity implements OnInit {
this.activity.time_created || Math.floor(Date.now() / 1000);
this.allowComments = this.activity.allow_comments;
this.activityAnalyticsOnViewService.checkVisibility(); // perform check
}
getOwnerIconTime() {
......
......@@ -5,6 +5,8 @@ import {
OnDestroy,
OnInit,
ViewChild,
SkipSelf,
Injector,
} from '@angular/core';
import { Location } from '@angular/common';
import { Event, NavigationStart, Router } from '@angular/router';
......@@ -23,6 +25,7 @@ import { MindsVideoComponent } from '../components/video/video.component';
import isMobileOrTablet from '../../../helpers/is-mobile-or-tablet';
import { ActivityService } from '../../../common/services/activity.service';
import { SiteService } from '../../../common/services/site.service';
import { ClientMetaService } from '../../../common/services/client-meta.service';
export type MediaModalParams = {
redirectUrl?: string;
......@@ -58,7 +61,7 @@ export type MediaModalParams = {
transition(':leave', [animate('300ms', style({ opacity: 0 }))]),
]),
],
providers: [ActivityService],
providers: [ActivityService, ClientMetaService],
})
export class MediaModalComponent implements OnInit, OnDestroy {
minds = window.Minds;
......@@ -120,8 +123,15 @@ export class MediaModalComponent implements OnInit, OnDestroy {
private overlayModal: OverlayModalService,
private router: Router,
private location: Location,
private site: SiteService
) {}
private site: SiteService,
private clientMetaService: ClientMetaService,
@SkipSelf() injector: Injector
) {
this.clientMetaService
.inherit(injector)
.setSource('single')
.setMedium('modal');
}
ngOnInit() {
// Prevent dismissal of modal when it's just been opened
......@@ -212,6 +222,7 @@ export class MediaModalComponent implements OnInit, OnDestroy {
url = `/pro/${this.site.pro.user_guid}${url}`;
}
this.clientMetaService.recordView(this.entity);
this.analyticsService.send('pageview', {
url,
});
......
import { ChangeDetectorRef, Component, OnInit, OnDestroy } from '@angular/core';
import {
ChangeDetectorRef,
Component,
OnInit,
OnDestroy,
SkipSelf,
Injector,
} from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs';
......@@ -11,6 +18,8 @@ import { AttachmentService } from '../../../services/attachment';
import { ContextService } from '../../../services/context.service';
import { MindsTitle } from '../../../services/ux/title';
import { ActivityService } from '../../../common/services/activity.service';
import { AnalyticsService } from '../../../services/analytics';
import { ClientMetaService } from '../../../common/services/client-meta.service';
@Component({
moduleId: module.id,
......@@ -23,6 +32,7 @@ import { ActivityService } from '../../../common/services/activity.service';
deps: [Client],
},
ActivityService,
ClientMetaService,
],
})
export class MediaViewComponent implements OnInit, OnDestroy {
......@@ -63,8 +73,15 @@ export class MediaViewComponent implements OnInit, OnDestroy {
public attachment: AttachmentService,
public context: ContextService,
private cd: ChangeDetectorRef,
protected activityService: ActivityService
) {}
protected activityService: ActivityService,
private clientMetaService: ClientMetaService,
@SkipSelf() injector: Injector
) {
this.clientMetaService
.inherit(injector)
.setSource('single')
.setMedium('single');
}
ngOnInit() {
this.title.setTitle('');
......@@ -125,6 +142,8 @@ export class MediaViewComponent implements OnInit, OnDestroy {
}
}
this.clientMetaService.recordView(this.entity);
this.detectChanges();
})
.catch(e => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment