...
 
Commits (6)
......@@ -66,12 +66,17 @@
>Donate</a>
<button
class="m-proChannelTopbar_subscribe"
(click)="!channel.subscribed ? subscribe($event) : unsubscribe($event)"
[hidden]="currentUser && (channel.guid === currentUser.guid)"
>
{{ !channel.subscribed ? 'Subscribe' : 'Subscribed' }}
<span>
class="m-proChannelTopbar__subscribe"
[class.m-proChannelTopbar__subscribe--subscribed]="channel.subscribed"
(click)="toggleSubscription($event)"
[hidden]="currentUser?.guid === channel.guid"
>
<span class="m-proChannelTopbar__subscribe--label">
<ng-container *ngIf="!channel.subscribed; else subscribedActionButton" i18n>Subscribe</ng-container>
<ng-template #subscribedActionButton><ng-container i18n>Subscribed</ng-container></ng-template>
</span>
<span class="m-proChannelTopbar__subscribe--counter">
{{ subscribers_count | abbr:0 }}
</span>
</button>
......@@ -133,3 +138,5 @@
<m-pro--channel-footer></m-pro--channel-footer>
</div>
</div>
<m-overlay-modal #overlayModal></m-overlay-modal>
......@@ -154,23 +154,31 @@ m-pro--channel {
}
}
.m-proChannelTopbar_subscribe {
.m-proChannelTopbar__subscribe {
appearance: none;
font-size: 12px;
letter-spacing: 1.25px;
box-shadow: none;
text-transform: uppercase;
padding: 8px 16px;
padding-left: 16px;
padding: 12px 16px;
font-family: 'Roboto', Helvetica, sans-serif;
cursor: pointer;
color: var(--text-color);
border: none;
background-color: var(--plain-background-color);
border-radius: 4px;
height: 36px;
margin-left: 16px;
color: var(--plain-background-color);
background-color: var(--primary-color);
&.m-proChannelTopbar__subscribe--subscribed {
color: var(--text-color);
background-color: var(--plain-background-color);
}
span {
margin-left: 4px;
.m-proChannelTopbar__subscribe--label {
opacity: 0.65;
}
.m-proChannelTopbar__subscribe--counter {
margin-left: 0.65em;
}
}
......@@ -179,7 +187,6 @@ m-pro--channel {
color: gray !important;
border: gray !important;
}
}
a.m-proChannelTopbar__navItem {
......
......@@ -7,7 +7,9 @@ import {
HostListener,
OnDestroy,
OnInit,
Injector
AfterViewInit,
Injector,
ViewChild
} from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from "@angular/router";
import { Session } from "../../../services/session";
......@@ -19,16 +21,18 @@ import { ProChannelService } from './channel.service';
import { SignupModalService } from '../../../modules/modals/signup/service';
import { OverlayModalService } from "../../../services/ux/overlay-modal";
import { ProUnsubscribeModalComponent } from './unsubscribe-modal/modal.component';
import { OverlayModalComponent } from '../../../common/components/overlay-modal/overlay-modal.component';
@Component({
providers: [
ProChannelService,
OverlayModalService,
],
selector: 'm-pro--channel',
templateUrl: 'channel.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ProChannelComponent implements OnInit, OnDestroy {
export class ProChannelComponent implements OnInit, AfterViewInit, OnDestroy {
username: string;
......@@ -62,6 +66,8 @@ export class ProChannelComponent implements OnInit, OnDestroy {
type: string = 'articles';
@ViewChild('overlayModal', { static: true }) protected overlayModal: OverlayModalComponent;
constructor(
protected element: ElementRef,
protected session: Session,
......@@ -82,6 +88,10 @@ export class ProChannelComponent implements OnInit, OnDestroy {
this.onResize();
}
ngAfterViewInit() {
this.modalService.setContainer(this.overlayModal);
}
shouldShowCategories(type: string) {
const routes = ['images', 'videos', 'articles', 'feed', 'communities'];
this.showCategories = routes.indexOf(type) !== -1;
......@@ -172,30 +182,29 @@ export class ProChannelComponent implements OnInit, OnDestroy {
this.detectChanges();
}
subscribe(e) {
e.preventDefault();
e.stopPropagation();
toggleSubscription($event) {
$event.preventDefault();
$event.stopPropagation();
if (!this.session.isLoggedIn()) {
this.router.navigate(['/pro', this.channel.username, 'signup']);
return false;
}
this.channelService.subscribe();
}
if (!this.channel.subscribed) {
if (!this.session.isLoggedIn()) {
this.router.navigate(['/pro', this.channel.username, 'signup']);
return false;
}
unsubscribe(e) {
this.modalService
.create(ProUnsubscribeModalComponent, this.channel,
{
class: 'm-overlayModal--unsubscribe'
}, this.injector)
.present();
this.channelService.subscribe();
} else {
this.modalService
.create(ProUnsubscribeModalComponent, this.channel,
{
class: 'm-overlayModal--unsubscribe'
}, this.injector)
.present();
}
}
bindCssVariables() {
const styles = this.channel.pro_settings.styles;
const modal: HTMLElement = document.querySelector('m-app m-overlay-modal');
for (const style in styles) {
if (!styles.hasOwnProperty(style)) {
......@@ -211,7 +220,6 @@ export class ProChannelComponent implements OnInit, OnDestroy {
const styleAttr = style.replace(/_/g, "-");
this.element.nativeElement
.style.setProperty(`--${styleAttr}`, styles[style]);
modal.style.setProperty(`--${styleAttr}`, styles[style]);
}
}
......@@ -237,7 +245,7 @@ export class ProChannelComponent implements OnInit, OnDestroy {
}
@HostListener('window:resize') onResize() {
this.collapseNavItems = window.innerWidth <= 992 ? true : false;
this.collapseNavItems = window.innerWidth <= 992;
}
get currentUser() {
......
......@@ -4,6 +4,8 @@ import { MindsUser } from '../../../interfaces/entities';
import { Client } from '../../../services/api/client';
import { EntitiesService } from '../../../common/services/entities.service';
import normalizeUrn from '../../../helpers/normalize-urn';
import { ProContentModalComponent } from './content-modal/modal.component';
import { OverlayModalService } from '../../../services/ux/overlay-modal';
@Injectable()
export class ProChannelService {
......@@ -112,6 +114,27 @@ export class ProChannelService {
return route;
}
open(entity, modalServiceContext: OverlayModalService) {
switch (this.getEntityTaxonomy(entity)) {
case 'group':
window.open(`${window.Minds.site_url}groups/profile/${entity.guid}`, '_blank');
break;
case 'object:blog':
window.open(`${window.Minds.site_url}${entity.route}/`, '_blank');
break;
case 'object:image':
case 'object:video':
modalServiceContext.create(ProContentModalComponent, entity, {
class: 'm-overlayModal--media'
}).present();
break;
}
}
getEntityTaxonomy(entity) {
return entity.type === 'object' ? `${entity.type}:${entity.subtype}` : entity.type;
}
async subscribe() {
this.currentChannel.subscribed = true;
......
<div class="m-pro--channel-home">
<div class="m-pro--channel-home--section" *ngIf="featuredContent?.length">
<h2 i18n>Featured Content</h2>
<div class="m-pro--channel-home--featured-content">
<m-pro--channel-tile
*ngFor="let entity of featuredContent"
......
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { ProChannelService } from '../channel.service';
import { OverlayModalService } from '../../../../services/ux/overlay-modal';
@Component({
selector: 'm-pro--channel-home',
......@@ -18,6 +19,7 @@ export class ProChannelHomeComponent implements OnInit {
constructor(
protected channelService: ProChannelService,
protected modalService: OverlayModalService,
protected cd: ChangeDetectorRef,
) {
}
......@@ -52,8 +54,8 @@ export class ProChannelHomeComponent implements OnInit {
this.detectChanges();
}
onContentClick(entity) {
onContentClick(entity: any) {
return this.channelService.open(entity, this.modalService);
}
get settings() {
......
<div class="m-pro--channel-list-modal">
<div class="m-pro--channel-list-modal--grid">
<div
class="m-pro--channel-list-modal--grid"
[class.m-pro--channel-list-modal--activities-grid]="type === 'activities'"
>
<ng-container *ngFor="let entity$ of (entities$ | async); let i = index">
<ng-container *ngIf="type === 'images' || type === 'videos' || type === 'blogs'">
<m-pro--channel-tile *ngIf="entity$ | async as entity"
[entity]="entity"
(click)="expand(entity)"
></m-pro--channel-tile>
<ng-container *ngIf="entity$ | async as entity">
<ng-container *ngIf="type === 'images' || type === 'videos' || type === 'blogs'">
<m-pro--channel-tile
[entity]="entity"
(click)="expand(entity)"
></m-pro--channel-tile>
</ng-container>
<ng-container *ngIf="type === 'activities'">
<minds-activity
[object]="entity"
></minds-activity>
</ng-container>
</ng-container>
</ng-container>
</div>
......
......@@ -6,6 +6,12 @@
display: grid;
grid-gap: 16px;
grid-template-columns: repeat(3, 1fr);
&.m-pro--channel-list-modal--activities-grid {
grid-template-columns: repeat(1, 1fr);
max-width: 500px;
margin: 0 auto;
}
}
m-overlay-modal {
......
......@@ -97,18 +97,8 @@ export class ProChannelListModal {
this.feedsService.loadMore();
}
async expand(entity) {
switch (this.getType(entity)) {
case 'object:blog':
window.open(`${window.Minds.site_url}${entity.route}/`, '_blank');
break;
case 'object:image':
case 'object:video':
this.modalService.create(ProContentModalComponent, entity, {
class: 'm-overlayModal--media'
}, this.injector).present();
break;
}
expand(entity: any) {
return this.channelService.open(entity, this.modalService);
}
private getType(entity: any) {
......
<div class="m-proChannelList__tools" *ngIf="query !== ''">
<!--<div class="m-proChannelListTools__algorithm">
<a [routerLink]="['/pro', channelUsername, getTypeForRoute(type), 'hot']" routerLinkActive="active" i18n>
<i class="material-icons">whatshot</i>
<span i18n>HOT</span>
</a>
<a [routerLink]="['/pro', channelUsername, getTypeForRoute(type), 'top']" routerLinkActive="active" i18n>
<i class="material-icons">trending_up</i>
<span i18n>TOP</span>
</a>
<a [routerLink]="['/pro', channelUsername, getTypeForRoute(type), 'latest']" routerLinkActive="active" i18n>
<i class="material-icons">timelapse</i>
<span i18n>LATEST</span>
</a>
</div>-->
<div class="m-proChannelListTools__searchResult"> <!--TODO add ngif after enable algorithm *ngIf="query !== ''"-->
<span> Showing results for: <strong> {{query}}</strong></span>
</div>
......@@ -33,6 +16,7 @@
<ng-container *ngIf="type === 'groups'">
<m-pro--channel--group-tile
[entity]="entity"
(onOpen)="onTileClicked(entity)"
[class.big]="i === 0 || i === 1"
></m-pro--channel--group-tile>
</ng-container>
......@@ -40,7 +24,6 @@
<ng-container *ngIf="type === 'activities'">
<minds-activity
[object]="entity"
(click)="onTileClicked(entity)"
></minds-activity>
</ng-container>
<li
......
......@@ -101,9 +101,13 @@ m-pro--channel-list {
grid-template-columns: 1fr;
& > li {
width: 500px;
max-width: 500px;
justify-self: center;
&.m-proChannelListContentList__seeMore {
width: 500px;
}
minds-activity {
min-width: 100%;
}
......@@ -113,7 +117,7 @@ m-pro--channel-list {
&:not(.m-proChannelListContent__normalList) {
& > li:nth-child(1), li:nth-child(2) {
& > video {
width: 500px;
max-width: 500px;
//max-height: 250px;
}
}
......@@ -167,6 +171,7 @@ m-pro--channel-list {
& > video {
width: 250px;
max-width: 100%;
}
}
}
......
......@@ -171,53 +171,7 @@ export class ProChannelListComponent implements OnInit, OnDestroy {
.present();
}
get channelUsername() {
return this.channelService.currentChannel.username
}
/**
* Returns the feed type on par to routes
* @param type feed type
*/
getTypeForRoute(type: string): string {
let routeType = '';
switch (type) {
case 'videos':
routeType = 'videos';
break;
case 'images':
routeType = 'images';
break;
case 'blogs':
routeType = 'articles';
break;
case 'groups':
routeType = 'groups';
break;
case 'activities':
routeType = 'feed';
break;
default:
throw new Error('Unknown type');
}
return routeType;
}
onTileClicked(entity: any) {
switch (this.getType(entity)) {
case 'object:blog':
window.open(`${window.Minds.site_url}${entity.route}/`, '_blank');
break;
case 'object:image':
case 'object:video':
this.modalService.create(ProContentModalComponent, entity, {
class: 'm-overlayModal--media'
}).present();
break;
}
}
private getType(entity: any) {
return entity.type === 'object' ? `${entity.type}:${entity.subtype}` : entity.type;
return this.channelService.open(entity, this.modalService);
}
}
import { Component, HostListener, Input } from '@angular/core';
import { Component, EventEmitter, HostListener, Input, Output } from '@angular/core';
@Component({
selector: 'm-pro--channel--group-tile',
......@@ -21,6 +21,8 @@ import { Component, HostListener, Input } from '@angular/core';
export class ProGroupTileComponent {
@Input() entity: any;
@Output('onOpen') onOpenEventEmitter: EventEmitter<boolean> = new EventEmitter();
minds = window.Minds;
getBanner() {
......@@ -32,6 +34,6 @@ export class ProGroupTileComponent {
}
@HostListener('click') onClick() {
window.open(`${window.Minds.site_url}groups/profile/${this.entity.guid}`, '_blank');
this.onOpenEventEmitter.emit(true);
}
}