Skip to content
Commits on Source (14)
......@@ -17,6 +17,7 @@ import { BlockListService } from './common/services/block-list.service';
import { FeaturesService } from './services/features.service';
import { ThemeService } from './common/services/theme.service';
import { BannedService } from './modules/report/banned/banned.service';
import { DiagnosticsService } from './services/diagnostics.service';
import { STANDALONE_ROUTES } from './modules/pro/pro.module';
@Component({
......@@ -53,7 +54,8 @@ export class Minds {
public blockListService: BlockListService,
public featuresService: FeaturesService,
public themeService: ThemeService,
private bannedService: BannedService
private bannedService: BannedService,
private diagnostics: DiagnosticsService,
) {
this.name = 'Minds';
......@@ -63,6 +65,9 @@ export class Minds {
}
async ngOnInit() {
this.diagnostics.setUser(this.minds.user);
this.diagnostics.listen(); // Listen for user changes
this.standalone = Boolean(window.Minds.pro);
if (!this.standalone) {
......
import { Cookie } from '../../services/cookie';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { environment } from '../../../environments/environment';
/**
* API Class
......@@ -68,6 +69,7 @@ export class MindsHttpClient {
const headers = new HttpHeaders({
'X-XSRF-TOKEN': XSRF_TOKEN,
'X-VERSION': environment.version,
});
return Object.assign(options, {
......
......@@ -6,7 +6,6 @@ import { ACCESS } from '../../../services/list-options';
@Component({
moduleId: module.id,
selector: 'minds-card-blog',
inputs: ['_blog : object'],
templateUrl: 'card.html',
})
......
......@@ -136,7 +136,7 @@
>explicit</i
>
<span i18n="@@M__COMMON__CONFIRM_18"
>Click to confirm your are 18+</span
>Click to confirm you are 18+</span
>
</span>
</div>
......@@ -169,7 +169,7 @@
>explicit</i
>
<span i18n="@@M__COMMON__CONFIRM_18"
>Click to confirm your are 18+</span
>Click to confirm you are 18+</span
>
</span>
</div>
......@@ -193,6 +193,9 @@
[torrent]="[
{ res: '360', key: comment.custom_data.guid + '/360.mp4' }
]"
[shouldPlayInModal]="true"
(videoMetadataLoaded)="setVideoDimensions($event)"
(mediaModalRequested)="openModal()"
>
</m-video>
</div>
......@@ -218,22 +221,21 @@
>explicit</i
>
<span i18n="@@M__COMMON__CONFIRM_18"
>Click to confirm your are 18+</span
>Click to confirm you are 18+</span
>
</span>
</div>
<a
target="_blank"
[routerLink]="['/media', comment.attachment_guid]"
*ngIf="comment.attachment_guid"
>
<a *ngIf="comment.attachment_guid">
<img
[src]="comment.custom_data[0].src"
class="mdl-shadow--2dp"
(error)="
comment.custom_data[0].src =
minds.cdn_assets_url + 'assets/logos/medium.png'
"
*ngIf="comment.custom_data"
class="mdl-shadow--2dp"
(click)="clickedImage()"
#batchImage
/>
</a>
......
......@@ -8,6 +8,8 @@ import {
ChangeDetectionStrategy,
OnChanges,
Input,
ViewChild,
ElementRef,
} from '@angular/core';
import { Session } from '../../../services/session';
......@@ -21,6 +23,11 @@ import { CommentsListComponent } from '../list/list.component';
import { TimeDiffService } from '../../../services/timediff.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Router } from '@angular/router';
import { FeaturesService } from '../../../services/features.service';
import { MindsVideoComponent } from '../../media/components/video/video.component';
import { MediaModalComponent } from '../../media/modal/modal.component';
import isMobile from '../../../helpers/is-mobile';
@Component({
moduleId: module.id,
......@@ -73,6 +80,11 @@ export class CommentComponent implements OnChanges {
translationInProgress: boolean;
translateToggle: boolean = false;
commentAge$: Observable<number>;
videoDimensions: Array<any> = null;
@ViewChild('player', { static: false }) player: MindsVideoComponent;
@ViewChild('batchImage', { static: false }) batchImage: ElementRef;
@Input() canEdit: boolean = false;
@Output() onReply = new EventEmitter();
......@@ -84,7 +96,9 @@ export class CommentComponent implements OnChanges {
public translationService: TranslationService,
private overlayModal: OverlayModalService,
private cd: ChangeDetectorRef,
private timeDiffService: TimeDiffService
private router: Router,
private timeDiffService: TimeDiffService,
protected featuresService: FeaturesService
) {}
ngOnInit() {
......@@ -300,4 +314,50 @@ export class CommentComponent implements OnChanges {
this.cd.detectChanges();
}
}
// * ATTACHMENT MEDIA MODAL * ---------------------------------------------------------------------
setVideoDimensions($event) {
this.videoDimensions = $event.dimensions;
this.comment.custom_data.dimensions = this.videoDimensions;
}
setImageDimensions() {
const img: HTMLImageElement = this.batchImage.nativeElement;
this.comment.custom_data[0].width = img.naturalWidth;
this.comment.custom_data[0].height = img.naturalHeight;
}
clickedImage() {
const isNotTablet = Math.min(screen.width, screen.height) < 768;
const pageUrl = `/media/${this.comment.entity_guid}`;
if (isMobile() && isNotTablet) {
this.router.navigate([pageUrl]);
return;
}
if (!this.featuresService.has('media-modal')) {
this.router.navigate([pageUrl]);
return;
} else {
if (
this.comment.custom_data[0].width === '0' ||
this.comment.custom_data[0].height === '0'
) {
this.setImageDimensions();
}
this.openModal();
}
}
openModal() {
this.comment.modal_source_url = this.router.url;
this.overlayModal
.create(MediaModalComponent, this.comment, {
class: 'm-overlayModal--media',
})
.present();
}
}
......@@ -138,7 +138,7 @@
>explicit</i
>
<span i18n="@@M__COMMON__CONFIRM_18"
>Click to confirm your are 18+</span
>Click to confirm you are 18+</span
>
</span>
</div>
......@@ -171,7 +171,7 @@
>explicit</i
>
<span i18n="@@M__COMMON__CONFIRM_18"
>Click to confirm your are 18+</span
>Click to confirm you are 18+</span
>
</span>
</div>
......@@ -196,6 +196,9 @@
[torrent]="[
{ res: '360', key: comment.custom_data.guid + '/360.mp4' }
]"
[shouldPlayInModal]="true"
(videoMetadataLoaded)="setVideoDimensions($event)"
(mediaModalRequested)="openModal()"
>
</m-video>
</div>
......@@ -221,22 +224,21 @@
>explicit</i
>
<span i18n="@@M__COMMON__CONFIRM_18"
>Click to confirm your are 18+</span
>Click to confirm you are 18+</span
>
</span>
</div>
<a
target="_blank"
[routerLink]="['/media', comment.attachment_guid]"
*ngIf="comment.attachment_guid"
>
<a *ngIf="comment.attachment_guid">
<img
[src]="comment.custom_data[0].src"
class="mdl-shadow--2dp"
(error)="
comment.custom_data[0].src =
minds.cdn_assets_url + 'assets/logos/medium.png'
"
*ngIf="comment.custom_data"
class="mdl-shadow--2dp"
(click)="clickedImage()"
#batchImage
/>
</a>
......
......@@ -8,6 +8,7 @@ import {
ChangeDetectionStrategy,
OnChanges,
Input,
ViewChild,
ElementRef,
} from '@angular/core';
......@@ -22,6 +23,11 @@ import { CommentsListComponent } from '../list/list.component';
import { TimeDiffService } from '../../../services/timediff.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Router } from '@angular/router';
import { FeaturesService } from '../../../services/features.service';
import { MindsVideoComponent } from '../../media/components/video/video.component';
import { MediaModalComponent } from '../../media/modal/modal.component';
import isMobile from '../../../helpers/is-mobile';
@Component({
selector: 'm-comment',
......@@ -71,6 +77,11 @@ export class CommentComponentV2 implements OnChanges {
translationInProgress: boolean;
translateToggle: boolean = false;
commentAge$: Observable<number>;
videoDimensions: Array<any> = null;
@ViewChild('player', { static: false }) player: MindsVideoComponent;
@ViewChild('batchImage', { static: false }) batchImage: ElementRef;
@Input() canEdit: boolean = false;
@Input() canDelete: boolean = false;
@Input() hideToolbar: boolean = false;
......@@ -85,7 +96,9 @@ export class CommentComponentV2 implements OnChanges {
private overlayModal: OverlayModalService,
private cd: ChangeDetectorRef,
private timeDiffService: TimeDiffService,
private el: ElementRef
private el: ElementRef,
private router: Router,
protected featuresService: FeaturesService
) {}
ngOnInit() {
......@@ -310,4 +323,50 @@ export class CommentComponentV2 implements OnChanges {
this.cd.detectChanges();
}
}
// * ATTACHMENT MEDIA MODAL * ---------------------------------------------------------------------
setVideoDimensions($event) {
this.videoDimensions = $event.dimensions;
this.comment.custom_data.dimensions = this.videoDimensions;
}
setImageDimensions() {
const img: HTMLImageElement = this.batchImage.nativeElement;
this.comment.custom_data[0].width = img.naturalWidth;
this.comment.custom_data[0].height = img.naturalHeight;
}
clickedImage() {
const isNotTablet = Math.min(screen.width, screen.height) < 768;
const pageUrl = `/media/${this.comment.entity_guid}`;
if (isMobile() && isNotTablet) {
this.router.navigate([pageUrl]);
return;
}
if (!this.featuresService.has('media-modal')) {
this.router.navigate([pageUrl]);
return;
} else {
if (
this.comment.custom_data[0].width === '0' ||
this.comment.custom_data[0].height === '0'
) {
this.setImageDimensions();
}
this.openModal();
}
}
openModal() {
this.comment.modal_source_url = this.router.url;
this.overlayModal
.create(MediaModalComponent, this.comment, {
class: 'm-overlayModal--media',
})
.present();
}
}
......@@ -52,6 +52,15 @@
View (PDF)
</a>
</li>
<li>
Site Admin -
<a
href="https://cdn-assets.minds.com/jobs/admin.pdf"
target="_blank"
>
View (PDF)
</a>
</li>
</ul>
</div>
<div
......
......@@ -210,9 +210,7 @@
i18n-title="@@M__COMMON__MATURE_CONTENT"
>explicit</i
>
<span i18n="@@M__COMMON__CONFIRM_18"
>Click to confirm your are 18+</span
>
<span i18n="@@M__COMMON__CONFIRM_18">Click to confirm you are 18+</span>
</span>
</div>
<minds-rich-embed [src]="activity" [maxheight]="480"></minds-rich-embed>
......@@ -283,9 +281,7 @@
i18n-title="@@M__COMMON__MATURE_CONTENT"
>explicit</i
>
<span i18n="@@M__COMMON__CONFIRM_18"
>Click to confirm your are 18+</span
>
<span i18n="@@M__COMMON__CONFIRM_18">Click to confirm you are 18+</span>
</span>
</div>
......@@ -298,9 +294,9 @@
[guid]="activity.custom_data.guid"
[playCount]="activity['play:count']"
[torrent]="[{ res: '360', key: activity.custom_data.guid + '/360.mp4' }]"
[isActivity]="true"
[shouldPlayInModal]="true"
(videoMetadataLoaded)="setVideoDimensions($event)"
(mediaModalRequested)="clickedVideo()"
(mediaModalRequested)="openModal()"
#player
>
<video-ads [player]="player" *ngIf="activity.monetized"></video-ads>
......@@ -321,9 +317,7 @@
i18n-title="@@M__COMMON__MATURE_CONTENT"
>explicit</i
>
<span i18n="@@M__COMMON__CONFIRM_18"
>Click to confirm your are 18+</span
>
<span i18n="@@M__COMMON__CONFIRM_18">Click to confirm you are 18+</span>
</span>
</div>
......@@ -349,9 +343,7 @@
i18n-title="@@M__COMMON__MATURE_CONTENT"
>explicit</i
>
<span i18n="@@M__COMMON__CONFIRM_18"
>Click to confirm your are 18+</span
>
<span i18n="@@M__COMMON__CONFIRM_18">Click to confirm you are 18+</span>
</span>
</div>
<a class="m-activity--image-link">
......
......@@ -502,6 +502,7 @@ export class Activity implements OnInit {
setVideoDimensions($event) {
this.videoDimensions = $event.dimensions;
this.activity.custom_data.dimensions = this.videoDimensions;
}
setImageDimensions() {
......@@ -511,18 +512,18 @@ export class Activity implements OnInit {
}
clickedImage() {
// Check if is mobile (not tablet)
if (isMobile() && Math.min(screen.width, screen.height) < 768) {
this.goToMediaPage();
const isNotTablet = Math.min(screen.width, screen.height) < 768;
const pageUrl = `/media/${this.activity.entity_guid}`;
if (isMobile() && isNotTablet) {
this.router.navigate([pageUrl]);
return;
}
if (!this.featuresService.has('media-modal')) {
// Non-canary
this.goToMediaPage();
this.router.navigate([pageUrl]);
return;
} else {
// Canary
if (
this.activity.custom_data[0].width === '0' ||
this.activity.custom_data[0].height === '0'
......@@ -533,13 +534,6 @@ export class Activity implements OnInit {
}
}
clickedVideo() {
// Already filtered out mobile users/non-canary in video.component.ts
// So this is just applicable to desktop/tablet in canary and should always show modal
this.activity.custom_data.dimensions = this.videoDimensions;
this.openModal();
}
openModal() {
this.activity.modal_source_url = this.router.url;
......@@ -554,10 +548,6 @@ export class Activity implements OnInit {
.present();
}
goToMediaPage() {
this.router.navigate([`/media/${this.activity.entity_guid}`]);
}
detectChanges() {
this.cd.markForCheck();
this.cd.detectChanges();
......
......@@ -166,6 +166,7 @@ export class Remind {
setVideoDimensions($event) {
this.videoDimensions = $event.dimensions;
this.activity.custom_data.dimensions = this.videoDimensions;
}
setImageDimensions() {
......@@ -175,14 +176,15 @@ export class Remind {
}
clickedImage() {
// Check if is mobile (not tablet)
if (isMobile() && Math.min(screen.width, screen.height) < 768) {
this.goToMediaPage();
const isNotTablet = Math.min(screen.width, screen.height) < 768;
const pageUrl = `/media/${this.activity.entity_guid}`;
if (isMobile() && isNotTablet) {
this.router.navigate([pageUrl]);
}
if (!this.featuresService.has('media-modal')) {
// Non-canary
this.goToMediaPage();
this.router.navigate([pageUrl]);
} else {
// Canary
if (
......@@ -195,13 +197,6 @@ export class Remind {
}
}
clickedVideo() {
// Already filtered out mobile users/non-canary in video.component.ts
// So this is just applicable to desktop/tablet in canary and should always show modal
this.activity.custom_data.dimensions = this.videoDimensions;
this.openModal();
}
openModal() {
this.activity.modal_source_url = this.router.url;
......@@ -215,8 +210,4 @@ export class Remind {
)
.present();
}
goToMediaPage() {
this.router.navigate([`/media/${this.activity.entity_guid}`]);
}
}
......@@ -214,7 +214,7 @@ describe('MindsVideo', () => {
// video.src = 'thisisavideo.mp4';
const video = new HTMLVideoElementMock();
comp.playerRef.getPlayer = () => <any>video;
comp.isActivity = false;
comp.shouldPlayInModal = false;
comp.showControls = true;
fixture.detectChanges(); // re-render
......
......@@ -64,9 +64,8 @@ export class MindsVideoComponent implements OnDestroy {
@Input() log: string | number;
@Input() muted: boolean = false;
@Input() poster: string = '';
@Input() isActivity: boolean = false;
@Input() isModal: boolean = false;
// @Input() isTheatre: boolean = false;
@Input() shouldPlayInModal: boolean = false;
@Output('finished') finished: EventEmitter<any> = new EventEmitter();
......@@ -217,7 +216,7 @@ export class MindsVideoComponent implements OnDestroy {
}
onMouseEnter() {
if (this.isActivity && this.featuresService.has('media-modal')) {
if (this.shouldPlayInModal && this.featuresService.has('media-modal')) {
return;
}
if (this.videoMetadataLoaded) {
......@@ -230,7 +229,7 @@ export class MindsVideoComponent implements OnDestroy {
onMouseLeave() {
if (
this.featuresService.has('media-modal') &&
(this.stageHover || this.isActivity)
(this.stageHover || this.shouldPlayInModal)
) {
return;
}
......@@ -440,13 +439,15 @@ export class MindsVideoComponent implements OnDestroy {
return;
}
if (isMobile() && Math.min(screen.width, screen.height) < 768) {
const isNotTablet = Math.min(screen.width, screen.height) < 768;
if (isMobile() && isNotTablet) {
this.isMobile = true;
this.toggle();
return;
}
if (this.isActivity && this.featuresService.has('media-modal')) {
if (this.shouldPlayInModal && this.featuresService.has('media-modal')) {
this.mediaModalRequested.emit();
return;
}
......
......@@ -28,6 +28,7 @@ import { MediaModalComponent } from './modal/modal.component';
import { ThumbnailSelectorComponent } from './components/thumbnail-selector.component';
import { CommentsModule } from '../comments/comments.module';
import { HashtagsModule } from '../hashtags/hashtags.module';
import { BlogModule } from '../blogs/blog.module';
const routes: Routes = [
{ path: 'media/videos/:filter', component: MediaVideosListComponent },
......@@ -60,6 +61,7 @@ const routes: Routes = [
PostMenuModule,
VideoModule,
HashtagsModule,
BlogModule,
],
declarations: [
MediaVideosListComponent,
......
......@@ -603,7 +603,9 @@ m-media--grid {
.m-comment__attachment {
img,
minds-video {
minds-video,
m-video {
max-width: 50%;
cursor: pointer;
}
}
......@@ -21,40 +21,10 @@
<!-- MEDIA STAGE -->
<div class="m-mediaModal__stage">
<div
class="m-mediaModal__mediaWrapper m-mediaModal__mediaWrapper--blog"
*ngIf="entityType === 'blog'"
[style.width]="mediaWidth + 'px'"
[style.height]="mediaHeight + 'px'"
>
<!-- [@slowFadeAnimation]="isLoading ? 'out' : 'in'" -->
<minds-banner
[src]="entity.thumbnail_src"
[object]="entity"
*ngIf="entity.header_bg"
></minds-banner>
<div class="mdl-grid" style="max-width:740px">
<div class="mdl-grid" style="width:100%">
<div class="mdl-cell mdl-cell--12-col">
<h1 class="m-blog--title">{{ entity.title }}</h1>
</div>
</div>
<div style="width:100%; padding:8px; position:relative;">
<div
class="mdl-cell mdl-cell--12-col minds-blog-body"
[innerHtml]="entity.description | safe"
[hidden]="!entity.description"
></div>
</div>
</div>
</div>
<!-- MEDIA: IMAGE -->
<div
class="m-mediaModal__mediaWrapper m-mediaModal__mediaWrapper--image"
*ngIf="!isVideo && entityType === 'image'"
class="m-mediaModal__mediaWrapper"
*ngIf="contentType === 'image'"
[style.width]="mediaWidth + 'px'"
[style.height]="mediaHeight + 'px'"
[@slowFadeAnimation]="isLoading ? 'out' : 'in'"
......@@ -70,8 +40,8 @@
<!-- MEDIA: VIDEO -->
<div
class="m-mediaModal__mediaWrapper m-mediaModal__mediaWrapper--video"
*ngIf="isVideo"
class="m-mediaModal__mediaWrapper"
*ngIf="contentType === 'video'"
[style.width]="mediaWidth + 'px'"
[style.height]="mediaHeight + 'px'"
>
......@@ -103,6 +73,17 @@
</m-video>
</div>
<!-- MEDIA: BLOG -->
<div
class="m-mediaModal__mediaWrapper m-mediaModal__mediaWrapper--blog"
*ngIf="contentType === 'blog'"
[style.width]="mediaWidth + 'px'"
[style.height]="mediaHeight + 'px'"
[@slowFadeAnimation]="isLoading ? 'out' : 'in'"
>
<m-blog-view [blog]="entity"></m-blog-view>
</div>
<!-- OVERLAY -->
<div
class="m-mediaModal__overlayContainer"
......@@ -116,7 +97,7 @@
*ngIf="!isFullscreen"
>
<a
[routerLink]="['/media', entity.entity_guid]"
[routerLink]="[pageUrl]"
(click)="$event.stopPropagation()"
>{{ title }}</a
>
......@@ -147,7 +128,7 @@
</a>
<div class="m-mediaModal__overlayTitleSeparator"></div>
<a
[routerLink]="['/media', entity.entity_guid]"
[routerLink]="[pageUrl]"
(click)="$event.stopPropagation()"
>{{ title }}</a
>
......@@ -243,7 +224,7 @@
</a>
<!-- PERMALINK -->
<a
[routerLink]="['/newsfeed', permalinkGuid]"
[routerLink]="[pageUrl]"
class="permalink m-ownerBlock__permalink"
>
<span class="m-ownerBlock__permalinkDate">{{
......@@ -282,12 +263,17 @@
<div
class="m-mediaModal__message mdl-card__supporting-text"
m-read-more
*ngIf="hasMessage"
*ngIf="
this.contentType !== 'blog' &&
(this.entity.title ||
this.entity.message ||
this.entity.description)
"
[maxHeightAllowed]="136"
>
<span
class="m-mature-message-content"
[innerHtml]="message | tags"
[innerHtml]="title | tags"
>
</span>
<m-read-more--button></m-read-more--button>
......@@ -295,17 +281,17 @@
<!-- ACTION BUTTONS -->
<div class="m-mediaModal__actionButtonsWrapper">
<div class="m-mediaModal__actionButtonsRow m-action-tabs">
<m-wire-button
*ngIf="session.getLoggedInUser().guid != entity.owner_guid"
[object]="entity"
(done)="wireSubmitted($event)"
></m-wire-button>
<minds-button-thumbs-up
[object]="entity"
></minds-button-thumbs-up>
<minds-button-thumbs-down
[object]="entity"
></minds-button-thumbs-down>
<m-wire-button
*ngIf="session.getLoggedInUser().guid != entity.owner_guid"
[object]="entity"
(done)="wireSubmitted($event)"
></m-wire-button>
<minds-button-remind [object]="entity"></minds-button-remind>
</div>
</div>
......
......@@ -70,7 +70,6 @@ m-overlay-modal {
@include m-theme() {
box-shadow: 0 12px 24px rgba(themed($m-black-always), 0.3);
}
// .m-mediaModal {} // has inline width/height
}
}
}
......@@ -88,7 +87,6 @@ m-overlay-modal {
}
.m-mediaModal__stageWrapper {
// Has inline width/line-height
float: left;
height: 100%;
min-height: 480px;
......@@ -150,23 +148,19 @@ m-overlay-modal {
.m-mediaModal__stage {
display: flex;
align-items: center;
font-size: 0;
height: 100%;
min-height: 402px;
position: relative;
text-align: center;
width: 100%;
}
.m-mediaModal__mediaWrapper {
// Has inline width/height
display: inline-block;
margin: 0 auto;
vertical-align: middle;
.m-mediaModal__media--image,
m-video {
// Has inline width/height
display: inline-block;
max-height: 100%;
max-width: 100%;
......@@ -204,6 +198,22 @@ m-overlay-modal {
}
}
}
&.m-mediaModal__mediaWrapper--blog {
overflow-x: hidden;
overflow-y: scroll;
line-height: 1.58 !important;
text-align: left;
.m-blog--image > img {
max-width: 100%;
}
.m-actions-block,
m-comments__tree {
display: none;
}
}
}
.m-mediaModal__overlayContainer {
......@@ -538,8 +548,14 @@ m-overlay-modal {
}
}
.m-mediaModal__message a {
text-decoration: none;
.m-mediaModal__message {
span {
white-space: pre-line;
word-wrap: break-word;
}
a {
text-decoration: none;
}
}
.m-mediaModal__actionButtonsWrapper {
......
......@@ -68,8 +68,7 @@ export class MediaModalComponent implements OnInit, OnDestroy {
isTablet: boolean = false;
isFullscreen: boolean = false;
isVideo: boolean = false;
entityType: string;
contentType: string = '';
aspectRatio: number;
modalWidth: number;
......@@ -77,8 +76,8 @@ export class MediaModalComponent implements OnInit, OnDestroy {
stageHeight: number;
mediaWidth: number;
mediaHeight: number;
entityWidth: number;
entityHeight: number;
entityWidth: number = 0;
entityHeight: number = 0;
maxStageWidth: number;
maxHeight: number;
......@@ -92,9 +91,7 @@ export class MediaModalComponent implements OnInit, OnDestroy {
thumbnail: string = '';
boosted: boolean = false;
ownerIconTime: string = '';
permalinkGuid: string = '';
hasMessage: boolean = true;
message: string = '';
pageUrl: string = '';
// Used for backdrop click detection hack
isOpen: boolean = false;
......@@ -108,8 +105,6 @@ export class MediaModalComponent implements OnInit, OnDestroy {
@Input('entity') set data(params: MediaModalParams) {
this.entity = params.entity;
this.redirectUrl = params.redirectUrl || null;
this.entityWidth = 0;
this.entityHeight = 0;
}
// Used to make sure video progress bar seeker / hover works
......@@ -128,21 +123,62 @@ export class MediaModalComponent implements OnInit, OnDestroy {
// Prevent dismissal of modal when it's just been opened
this.isOpenTimeout = setTimeout(() => (this.isOpen = true), 20);
this.boosted = this.entity.boosted || this.entity.p2p_boosted;
switch (this.entity.type) {
case 'activity':
this.title =
this.entity.message ||
this.entity.title ||
`${this.entity.ownerObj.name}'s post`;
this.entity.guid = this.entity.entity_guid || this.entity.guid;
this.thumbnail = `${this.minds.cdn_url}fs/v1/thumbnail/${this.entity.entity_guid}/xlarge`;
switch (this.entity.custom_type) {
case 'video':
this.contentType = 'video';
break;
case 'batch':
this.contentType = 'image';
}
break;
case 'object':
switch (this.entity.subtype) {
case 'video':
this.contentType = 'video';
this.title = this.entity.title;
break;
case 'image':
this.contentType = 'image';
this.thumbnail = `${this.minds.cdn_url}fs/v1/thumbnail/${this.entity.guid}/xlarge`;
break;
case 'blog':
this.contentType = 'blog';
this.title = this.entity.title;
this.entity.guid = this.entity.guid;
this.entity.entity_guid = this.entity.guid;
}
break;
case 'comment':
this.contentType =
this.entity.custom_type === 'video' ? 'video' : 'image';
this.title =
this.entity.message ||
this.entity.title ||
this.entity.description ||
`${this.entity.ownerObj.name}'s post`;
this.entity.guid = this.entity.attachment_guid;
this.entity.entity_guid = this.entity.attachment_guid;
this.thumbnail = `${this.minds.cdn_url}fs/v1/thumbnail/${this.entity.attachment_guid}/xlarge`;
break;
}
// Set title
if (!this.entity.title) {
if (!this.entity.message) {
this.title = `${this.entity.ownerObj.name}'s post`;
this.hasMessage = false;
} else {
this.title = this.entity.message;
}
if (this.contentType !== 'blog') {
this.pageUrl = `/media/${this.entity.entity_guid}`;
} else {
this.title = this.entity.title;
this.pageUrl = this.entity.route
? `/${this.entity.route}`
: `/blog/view${this.entity.guid}`;
}
this.message = this.hasMessage ? this.title : null;
this.boosted = this.entity.boosted || this.entity.p2p_boosted || false;
// Set ownerIconTime
const session = this.session.getLoggedInUser();
......@@ -152,44 +188,17 @@ export class MediaModalComponent implements OnInit, OnDestroy {
this.ownerIconTime = this.entity.ownerObj.icontime;
}
this.permalinkGuid = this.entity.guid
? this.entity.guid
: this.entity.entity_guid;
// Allow comment tree to work
if (!this.entity.guid) {
this.entity.guid = this.entity.entity_guid;
}
this.isTablet =
isMobileOrTablet() && Math.min(screen.width, screen.height) >= 768;
this.isVideo = this.entity.custom_type === 'video';
this.entityType =
this.entity.custom_type || this.getEntityType(this.entity);
if (this.entityType === 'blog') {
this.isLoaded();
}
this.analyticsService.send('pageview', {
url: `/media/${this.entity.entity_guid}?ismodal=true`,
url: `${this.pageUrl}?ismodal=true`,
});
// * LOCATION & ROUTING * -----------------------------------------------------------------------------------
// Change the url to point to media page so user can easily share link
// (but don't actually redirect)
if (this.redirectUrl) {
this.location.replaceState(this.redirectUrl);
} else if (this.entityType === 'blog') {
this.location.replaceState(
`${this.session.getLoggedInUser().username}/blog/${this.entity.slug}-${
this.entity.guid
}`
);
} else {
this.location.replaceState(`/media/${this.entity.entity_guid}`);
}
this.location.replaceState(this.pageUrl);
// When user clicks a link from inside the modal
this.routerSubscription = this.router.events.subscribe((event: Event) => {
......@@ -210,19 +219,18 @@ export class MediaModalComponent implements OnInit, OnDestroy {
// * DIMENSION CALCULATIONS * ---------------------------------------------------------------------
if (!this.isVideo && this.entityType === 'image') {
// Image
this.entityWidth = this.entity.custom_data[0].width;
this.entityHeight = this.entity.custom_data[0].height;
this.thumbnail = `${this.minds.cdn_url}fs/v1/thumbnail/${this.entity.entity_guid}/xlarge`;
} else if (this.entityType === 'blog') {
this.entityWidth = this.entity.custom_data[0].dimensions.width;
this.entityHeight = this.entity.custom_data[0].dimensions.height;
this.thumbnail = `${this.minds.cdn_url}fs/v1/thumbnail/${this.entity.entity_guid}/xlarge`;
} else {
this.entityWidth = this.entity.custom_data.dimensions.width;
this.entityHeight = this.entity.custom_data.dimensions.height;
this.thumbnail = this.entity.custom_data.thumbnail_src; // Not currently used
switch (this.contentType) {
case 'video':
this.entityWidth = this.entity.custom_data.dimensions.width;
this.entityHeight = this.entity.custom_data.dimensions.height;
break;
case 'image':
this.entityWidth = this.entity.custom_data[0].width;
this.entityHeight = this.entity.custom_data[0].height;
break;
case 'blog':
this.entityWidth = window.innerWidth;
this.entityHeight = window.innerHeight;
}
this.aspectRatio = this.entityWidth / this.entityHeight;
......@@ -237,6 +245,26 @@ export class MediaModalComponent implements OnInit, OnDestroy {
calculateDimensions() {
if (!this.isFullscreen) {
if (this.contentType === 'blog') {
this.mediaHeight = Math.max(
this.minStageHeight,
window.innerHeight - this.padding * 2
);
this.mediaWidth = Math.max(
this.minStageWidth,
window.innerWidth - this.contentWidth - this.padding * 2
);
this.stageHeight = this.mediaHeight;
this.stageWidth = this.mediaWidth;
this.modalWidth = this.stageWidth + this.contentWidth;
if (this.isLoading) {
this.isLoaded();
}
return;
}
this.setHeightsAsTallAsPossible();
// After heights are set, check that scaled width isn't too wide or narrow
......@@ -272,16 +300,23 @@ export class MediaModalComponent implements OnInit, OnDestroy {
this.stageWidth = windowWidth;
this.stageHeight = windowHeight;
if (this.entity.custom_type === 'image') {
// For images, set mediaHeight as tall as possible but not taller than instrinsic height
this.mediaHeight =
this.entityHeight < windowHeight ? this.entityHeight : windowHeight;
} else {
// It's ok if videos are taller than intrinsic height
this.mediaHeight = windowHeight;
switch (this.contentType) {
case 'blog':
this.mediaHeight = windowHeight;
this.mediaWidth = windowWidth;
return;
case 'image':
// For images, set mediaHeight as tall as possible but not taller than instrinsic height
this.mediaHeight =
this.entityHeight < windowHeight ? this.entityHeight : windowHeight;
break;
case 'video':
// It's ok if videos are taller than intrinsic height
this.mediaHeight = windowHeight;
}
this.mediaWidth = this.scaleWidth();
this.mediaWidth =
this.contentType === 'blog' ? windowWidth : this.scaleWidth();
if (this.mediaWidth > windowWidth) {
// Width was too wide, need to rescale heights so width fits
......@@ -290,7 +325,7 @@ export class MediaModalComponent implements OnInit, OnDestroy {
}
}
if (this.isVideo) {
if (this.contentType === 'video') {
this.entityHeight = this.mediaHeight;
this.entityWidth = this.mediaWidth;
}
......@@ -305,7 +340,7 @@ export class MediaModalComponent implements OnInit, OnDestroy {
this.stageHeight = Math.max(this.maxHeight, this.minStageHeight);
// Set mediaHeight as tall as stage but no larger than intrinsic height
if (!this.isVideo && this.entityHeight < this.stageHeight) {
if (this.contentType !== 'video' && this.entityHeight < this.stageHeight) {
// Image is shorter than stage; scale down stage
this.mediaHeight = this.entityHeight;
this.stageHeight = Math.max(this.mediaHeight, this.minStageHeight);
......@@ -446,7 +481,7 @@ export class MediaModalComponent implements OnInit, OnDestroy {
onMouseEnterStage() {
this.overlayVisible = true;
if (this.isVideo) {
if (this.contentType === 'video') {
// Make sure progress bar seeker is updating when video controls are visible
this.videoComponent.stageHover = true;
this.videoComponent.onMouseEnter();
......@@ -456,7 +491,7 @@ export class MediaModalComponent implements OnInit, OnDestroy {
onMouseLeaveStage() {
this.overlayVisible = false;
if (this.isVideo) {
if (this.contentType === 'video') {
// Stop updating progress bar seeker when controls aren't visible
this.videoComponent.stageHover = false;
this.videoComponent.onMouseLeave();
......@@ -488,12 +523,6 @@ export class MediaModalComponent implements OnInit, OnDestroy {
}
}
getEntityType(entity: any) {
return entity.type === 'object'
? `${entity.type}:${entity.subtype}`
: entity.type;
}
ngOnDestroy() {
if (this.routerSubscription) {
this.routerSubscription.unsubscribe();
......
......@@ -68,7 +68,7 @@
>explicit</i
>
<span i18n="@@M__COMMON__CONFIRM_18"
>Click to confirm your are 18+</span
>Click to confirm you are 18+</span
>
</span>
</div>
......
......@@ -122,6 +122,7 @@ export class NewsfeedBoostRotatorComponent {
load() {
try {
this.feedsService.clear(); // Fresh each time
this.feedsService
.setEndpoint('api/v2/boost/feed')
.setParams({
......@@ -262,8 +263,7 @@ export class NewsfeedBoostRotatorComponent {
if (this.currentPosition + 1 > this.boosts.length - 1) {
//this.currentPosition = 0;
try {
this.feedsService.fetch();
this.feedsService.loadMore();
this.load();
this.currentPosition++;
} catch (e) {
this.currentPosition = 0;
......