Commit 2f56ef5f authored by Marcelo Rivera's avatar Marcelo Rivera

(feat): pro channel page

1 merge request!459WIP: (feat): Minds Pro
Pipeline #72943376 passed with stages
in 31 minutes
<div class="m-proChannel__topbar">
<img class="m-proChannelTopbar__logo"
src="https://yt3.ggpht.com/a/AGF-l7-24Iy1c6QKw0mRaO56Fj5jUcGP5Al9J7_2FQ=s900-mo-c-c0xffffffff-rj-k-no">
<input>
<a routerLink="/pro/{{username}}/videos" [routerLinkActive]="'active'">Videos</a>
<a routerLink="/pro/{{username}}/images" [routerLinkActive]="'active'">Images</a>
<a routerLink="/pro/{{username}}/articles" [routerLinkActive]="'active'">Articles</a>
<a routerLink="/pro/{{username}}/groups" [routerLinkActive]="'active'">Groups</a>
<a routerLink="/pro/{{username}}/donate" [routerLinkActive]="'active'">Donate</a>
<a routerLink="/pro/{{username}}/signup" [routerLinkActive]="'active'">Signup | Login</a>
</div>
<div class="m-proChannel__body">
<router-outlet></router-outlet>
</div>
@import "defaults";
m-pro--channel {
display: grid;
grid-template-rows: repeat(2, 100px) 1fr;
grid-template-columns: repeat(12, 1fr);
background-image: url("http://localhost:8080/fs/v1/banners/984862704493895680/fat/1560185652");
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
.m-proChannel__topbar {
grid-row: 1 / span 1;
grid-column: 1 / span 12;
display: flex;
align-items: center;
padding-left: $minds-padding * 4;
.m-proChannelTopbar__logo {
max-height: 100%;
}
& > * {
padding-right: 16px;
}
}
a {
text-decoration: none;
padding: $minds-padding * 2;
font-size: 24px;
}
.m-proChannel__body {
grid-row: 3 / span 1;
grid-column: 1 / span 12;
padding: 0 $minds-padding * 4;
}
m-pro--channel h1 {
font-size: 70px;
font-weight: bold;
}
// colors
a.active, a:hover {
color: #4690D6 !important;
}
a, h1, h2, h3, h4, h5, p, i {
color: white !important;
}
}
import { Component } from '@angular/core';
import { ActivatedRoute, Router } from "@angular/router";
import { Session } from "../../../services/session";
import { Subscription } from "rxjs";
import { MindsUser } from "../../../interfaces/entities";
import { Client } from "../../../services/api/client";
import { Title } from "@angular/platform-browser";
import { ProService } from "../pro.service";
@Component({
selector: 'm-pro--channel',
templateUrl: 'channel.component.html'
})
export class ProChannelComponent {
minds = window.Minds;
username: string;
user: MindsUser = null;
error: string;
paramsSubscription: Subscription;
constructor(
public session: Session,
private proService: ProService,
private client: Client,
private title: Title,
private router: Router,
private route: ActivatedRoute,
) {
this.paramsSubscription = this.route.params.subscribe(params => {
if (params['username']) {
this.username = params['username'];
}
if (!this.session.isLoggedIn()) {
this.router.navigate(['/pro', this.username, 'signup']);
}
this.loadChannel();
});
}
async loadChannel() {
try {
this.user = await this.proService.loadChannel(this.username);
this.title.setTitle(`${this.user.name} (@${this.user.username})`);
} catch (e) {
this.error = e.getMessage();
}
}
}
m-pro--channel-list {
h1 {
font-size: 90px;
font-weight: bold;
}
.m-proChannelList__content {
display: flex;
//align-items: center;
justify-content: center;
& > i.material-icons {
font-size: 100px;
margin-top: 100px;
height: fit-content;
}
}
ul.m-proChannelListContent__list {
display: grid;
//grid-template-rows: repeat(15, 1fr);
//grid-template-columns: repeat(17, 1fr);
//grid-template-rows: repeat(2, 1fr);
grid-template-columns: repeat(4, 1fr);
grid-gap: $minds-padding * 4 $minds-padding * 4;
list-style: none;
padding: 0;
li {
grid-column: span 1;
//border: 1px solid blue;
display: flex;
justify-content: center;
align-items: center;
//width: 100px;
//height:
&:nth-child(1), &:nth-child(2) {
& > video {
width: 500px;
//max-height: 250px;
}
}
&:nth-child(1) {
grid-column: span 2;
margin-bottom: $minds-padding * 4;
justify-content: flex-start;
}
&:nth-child(2) {
grid-column: 3 / span 2;
margin-bottom: $minds-padding * 4;
justify-content: flex-end;
}
& > video {
width: 250px;
}
}
@media screen and (min-width: 1px) and (max-width: $max-mobile) {
grid-template-columns: 1fr;
li {
&:nth-child(1), &:nth-child(2) {
margin-bottom: 0;
justify-content: center;
grid-column: span 1;
& > video {
//max-height: 150px;
width: 300px;
}
}
}
}
}
}
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from "@angular/router";
import { Subscription } from "rxjs";
import { FeedsService } from "../../../../common/services/feeds.service";
import { ProService } from "../../pro.service";
@Component({
selector: 'm-pro--channel-list',
template: `
<!-- TODO: i18n -->
<h1>{{type | titlecase}}</h1>
<div class="m-proChannelList__content">
<i class="material-icons">keyboard_arrow_left</i>
<ul class="m-proChannelListContent__list">
<!-- <li *ngFor="let entity of (feedsService.feed | async); let i = index">-->
<!-- TODO: custom tile here -->
<!-- </li>-->
<li>
<video src="https://cdn-cinemr.minds.com/cinemr_com/943902545938489353/720.mp4"></video>
</li>
<li>
<video src="https://cdn-cinemr.minds.com/cinemr_com/943902545938489353/720.mp4"></video>
</li>
<li>
<video src="https://cdn-cinemr.minds.com/cinemr_com/943902545938489353/720.mp4"></video>
</li>
<li>
<video src="https://cdn-cinemr.minds.com/cinemr_com/943902545938489353/720.mp4"></video>
</li>
<li>
<video src="https://cdn-cinemr.minds.com/cinemr_com/943902545938489353/720.mp4"></video>
</li>
<li>
<video src="https://cdn-cinemr.minds.com/cinemr_com/943902545938489353/720.mp4"></video>
</li>
<li>
<video src="https://cdn-cinemr.minds.com/cinemr_com/943902545938489353/720.mp4"></video>
</li>
<li>
<video src="https://cdn-cinemr.minds.com/cinemr_com/943902545938489353/720.mp4"></video>
</li>
</ul>
<i class="material-icons">keyboard_arrow_right</i>
</div>
<!-- TODO: add infinite scroll or something to load more -->
`
})
export class ProChannelListComponent implements OnInit {
type: string;
paramsSubscription: Subscription;
constructor(
public feedsService: FeedsService,
private proService: ProService,
private route: ActivatedRoute,
private router: Router,
) {
this.paramsSubscription = this.route.params.subscribe(params => {
if (params['type']) {
this.type = params['type'];
}
switch (this.type) {
case 'videos':
break;
case 'images':
break;
case 'articles':
break;
case 'groups':
break;
default:
}
this.load();
});
}
ngOnInit() {
}
async load(refresh: boolean = false) {
if (!refresh) {
return;
}
if (refresh) {
this.feedsService.clear();
}
// this.detectChanges();
try {
this.feedsService
.setEndpoint(`api/v2/feeds/container/${this.proService.currentChannel.guid}/${this.type}`)
.setLimit(8)
.fetch();
} catch (e) {
console.error('ProChannelListComponent.load', e);
}
// this.detectChanges();
}
loadNext() {
this.feedsService.loadMore();
}
}
m-pro--channel-signup {
display: flex;
align-items: center;
justify-content: center;
}
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from "@angular/router";
import { Subscription } from "rxjs";
import { Session } from "../../../../services/session";
@Component({
selector: 'm-pro--channel-signup',
template: `
<div class="m-ProChannelSignup__Text">
<!-- TODO: this text should be dynamic -->
<h2>Independent.</h2>
<h2>Community-owned.</h2>
<h2>Decentralized News</h2>
</div>
<div class="m-ProChannelSignup__SignupForm">
<minds-form-register (done)="registered()"></minds-form-register>
</div>
`
})
export class ProChannelSignupComponent implements OnInit {
username: string;
paramsSubscription: Subscription;
constructor(
public session: Session,
private router: Router,
private route: ActivatedRoute,
) {
this.paramsSubscription = this.route.params.subscribe(params => {
if (params['username']) {
this.username = params['username'];
}
if (this.session.isLoggedIn()) {
this.router.navigate(['/pro', this.username]);
}
});
}
ngOnInit() {
}
registered() {
this.router.navigate(['pro', this.username]);
}
}
......@@ -6,11 +6,25 @@ import { CommonModule } from '../../common/common.module';
import { ProService } from './pro.service';
import { ProMarketingComponent } from './marketing.component';
import { ProSubscriptionComponent } from './subscription.component';
import { ProChannelComponent } from "./channel/channel.component";
import { ProChannelSignupComponent } from "./channel/signup/signup.component";
import { MindsFormsModule } from "../forms/forms.module";
import { ProChannelListComponent } from "./channel/list/list.component";
const routes: Routes = [
{
path: 'pro',
component: ProMarketingComponent,
children: [
{ path: '', component: ProMarketingComponent, },
{
path: ':username', component: ProChannelComponent,
children: [
{ path: '', redirectTo: 'articles', pathMatch: 'full' },
{ path: 'signup', component: ProChannelSignupComponent },
{ path: ':type', component: ProChannelListComponent },
]
},
]
},
];
......@@ -21,6 +35,7 @@ const routes: Routes = [
ReactiveFormsModule,
CommonModule,
RouterModule.forChild(routes),
MindsFormsModule,
],
providers: [
ProService,
......@@ -28,10 +43,14 @@ const routes: Routes = [
declarations: [
ProMarketingComponent,
ProSubscriptionComponent,
ProChannelComponent,
ProChannelSignupComponent,
ProChannelListComponent,
],
exports: [],
entryComponents: [
ProMarketingComponent,
],
})
export class ProModule {}
export class ProModule {
}
import { Injectable } from '@angular/core';
import { Client } from '../../services/api/client';
import { MindsUser } from "../../interfaces/entities";
import { MindsChannelResponse } from "../../interfaces/responses";
@Injectable()
export class ProService {
currentChannel: MindsUser;
constructor(
protected client: Client,
) { }
......@@ -27,4 +31,21 @@ export class ProService {
await this.client.delete('api/v2/pro');
return true;
}
async loadChannel(username: string) {
try {
const response: MindsChannelResponse = <MindsChannelResponse>await this.client.get(`api/v1/channel/${username}`);
this.currentChannel = response.channel;
return this.currentChannel;
} catch (e) {
if (e.status === 0) {
throw new Error('Sorry, there was a timeout error.');
} else {
console.log('couldn\'t load channel', e);
throw new Error('Sorry, the channel couldn\'t be found');
}
}
}
}
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