| @@ -17,6 +17,10 @@ const routes: Routes = [ | |||||
| { | { | ||||
| path: 'more', | path: 'more', | ||||
| loadChildren: () => import('./more/more.module').then( m => m.MorePageModule) | loadChildren: () => import('./more/more.module').then( m => m.MorePageModule) | ||||
| }, | |||||
| { | |||||
| path: 'home-details', | |||||
| loadChildren: () => import('./home-details/home-details.module').then( m => m.HomeDetailsPageModule) | |||||
| } | } | ||||
| ]; | ]; | ||||
| @NgModule({ | @NgModule({ | ||||
| @@ -0,0 +1,17 @@ | |||||
| import { NgModule } from '@angular/core'; | |||||
| import { Routes, RouterModule } from '@angular/router'; | |||||
| import { HomeDetailsPage } from './home-details.page'; | |||||
| const routes: Routes = [ | |||||
| { | |||||
| path: '', | |||||
| component: HomeDetailsPage | |||||
| } | |||||
| ]; | |||||
| @NgModule({ | |||||
| imports: [RouterModule.forChild(routes)], | |||||
| exports: [RouterModule], | |||||
| }) | |||||
| export class HomeDetailsPageRoutingModule {} | |||||
| @@ -0,0 +1,20 @@ | |||||
| import { NgModule } from '@angular/core'; | |||||
| import { CommonModule } from '@angular/common'; | |||||
| import { FormsModule } from '@angular/forms'; | |||||
| import { IonicModule } from '@ionic/angular'; | |||||
| import { HomeDetailsPageRoutingModule } from './home-details-routing.module'; | |||||
| import { HomeDetailsPage } from './home-details.page'; | |||||
| @NgModule({ | |||||
| imports: [ | |||||
| CommonModule, | |||||
| FormsModule, | |||||
| IonicModule, | |||||
| HomeDetailsPageRoutingModule | |||||
| ], | |||||
| declarations: [HomeDetailsPage] | |||||
| }) | |||||
| export class HomeDetailsPageModule {} | |||||
| @@ -0,0 +1,74 @@ | |||||
| <ion-content> | |||||
| <button (click)="back()" | |||||
| class="close-article-button active"> | |||||
| <ion-icon name="close"></ion-icon> | |||||
| </button> | |||||
| <div class="image-holder"> | |||||
| <figure> | |||||
| <img [src]="newsDetails.image"> | |||||
| </figure> | |||||
| <button *ngIf="newsDetails.type === 'VIDEO'"> | |||||
| <ion-icon name="play"></ion-icon> | |||||
| </button> | |||||
| </div> | |||||
| <section class="content"> | |||||
| <h4> {{ newsDetails.heading }} </h4> | |||||
| <div class="details"> | |||||
| {{ newsDetails.description }} | |||||
| </div> | |||||
| </section> | |||||
| <section class="comments"> | |||||
| <header> Comments </header> | |||||
| <ul> | |||||
| <li *ngFor="let comment of newsDetails.comments"> | |||||
| <p> {{ comment.comment }} <label> - {{ comment.user }} </label> </p> | |||||
| <button (click)="comment.isLiked = !comment.isLiked" | |||||
| [ngClass]="{'active' : comment.isLiked}"> | |||||
| <ion-icon *ngIf="!comment.isLiked" name="heart-outline"></ion-icon> | |||||
| <ion-icon *ngIf="comment.isLiked" name="heart"></ion-icon> | |||||
| <span> {{ comment.isLiked ? comment.likes + 1 : comment.likes }} </span> | |||||
| </button> | |||||
| </li> | |||||
| <div class="input-holder" id="comment-input"> | |||||
| <input type="text" placeholder="Type your comment" [(ngModel)]="myComment"> | |||||
| <button (click)="postComment()"> <ion-icon name="send"></ion-icon> </button> | |||||
| </div> | |||||
| </ul> | |||||
| </section> | |||||
| <section class="action-buttons"> | |||||
| <section class="shortcuts"> | |||||
| <button class="wide-button" (click)="newsDetails.isLiked = !newsDetails.isLiked" | |||||
| [ngClass]="{'active' : newsDetails.isLiked}"> | |||||
| <ion-icon *ngIf="!newsDetails.isLiked" name="heart-outline"></ion-icon> | |||||
| <ion-icon *ngIf="newsDetails.isLiked" name="heart"></ion-icon> | |||||
| <span> {{ newsDetails.isLiked ? newsDetails.likes + 1 : newsDetails.likes }} </span> | |||||
| </button> | |||||
| <button> | |||||
| <ion-icon name="share-social-outline"></ion-icon> | |||||
| </button> | |||||
| </section> | |||||
| <section class="shortcuts"> | |||||
| <button (click)="newsDetails.isBookmarked = !newsDetails.isBookmarked" | |||||
| [ngClass]="{'active' : newsDetails.isBookmarked}"> | |||||
| <ion-icon *ngIf="!newsDetails.isBookmarked" name="bookmark-outline"></ion-icon> | |||||
| <ion-icon *ngIf="newsDetails.isBookmarked" name="bookmark"></ion-icon> | |||||
| </button> | |||||
| <button class="wide-button" (click)="scrollToAddComment()"> | |||||
| <ion-icon name="chatbubble-outline"></ion-icon> | |||||
| <span> {{ newsDetails.comments.length }} </span> | |||||
| </button> | |||||
| </section> | |||||
| </section> | |||||
| </ion-content> | |||||
| @@ -0,0 +1,297 @@ | |||||
| .close-article-button { | |||||
| width: 40px; | |||||
| height: 40px; | |||||
| position: fixed; | |||||
| top: 10px; | |||||
| right: 10px; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| background-color: rgba(#ffff, 0.5); | |||||
| border-radius: 50%; | |||||
| z-index: 3; | |||||
| opacity: 0; | |||||
| transform: translateY(10px); | |||||
| transition: opacity 0.3s, transform 0.3s; | |||||
| &.active { | |||||
| animation: fadeInFromBottom 0.5s forwards; | |||||
| } | |||||
| ion-icon { | |||||
| color: white; | |||||
| font-size: 20px; | |||||
| } | |||||
| } | |||||
| @keyframes fadeInFromBottom { | |||||
| 0% { | |||||
| opacity: 0; | |||||
| transform: translateY(30px); | |||||
| } | |||||
| 100% { | |||||
| opacity: 1; | |||||
| transform: translateY(0px); | |||||
| } | |||||
| } | |||||
| .image-holder { | |||||
| position: sticky; | |||||
| position: -webkit-sticky; | |||||
| top: 0; | |||||
| height: 40%; | |||||
| overflow: hidden; | |||||
| button { | |||||
| width: 40px; | |||||
| height: 40px; | |||||
| position: absolute; | |||||
| bottom: 10px; | |||||
| right: 10px; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| background-color: rgba(var(--brand-red-rgb), 0.5); | |||||
| border-radius: 50%; | |||||
| transform: translate(calc(-50vw + 40px), -15vh); | |||||
| ion-icon { | |||||
| color: white; | |||||
| font-size: 20px; | |||||
| transition: color 0.3s; | |||||
| } | |||||
| } | |||||
| figure { | |||||
| margin: 0; | |||||
| display: block; | |||||
| width: 100%; | |||||
| height: 100%; | |||||
| filter: brightness(30%); | |||||
| img { | |||||
| height: 100%; | |||||
| object-fit: cover; | |||||
| display: block; | |||||
| width: 100%; | |||||
| } | |||||
| } | |||||
| } | |||||
| .content { | |||||
| background-color: white; | |||||
| padding: 0px 5% 5% 5%; | |||||
| margin: 0 auto; | |||||
| border-radius: 0px; | |||||
| transition: border-radius 0.3s, transform 0.3s, width 0.3s, margin 0.3s, box-shadow 0.3s; | |||||
| border-bottom: 1px solid rgba(var(--light-grey-rgb), 0.3); | |||||
| z-index: 2; | |||||
| width: 90%; | |||||
| height: auto; | |||||
| position: relative; | |||||
| border-radius: 10px; | |||||
| overflow: auto; | |||||
| border-width: 0px; | |||||
| box-shadow: 0px 0px 15px rgba(var(--light-grey-rgb), 0.3); | |||||
| animation: showUpContent 0.5s forwards; | |||||
| } | |||||
| @keyframes showUpContent { | |||||
| 0% { | |||||
| transform: translateY(0px); | |||||
| } | |||||
| 100% { | |||||
| transform: translateY(-40px); | |||||
| } | |||||
| } | |||||
| h4 { | |||||
| font-size: 1.2rem; | |||||
| margin: 0px; | |||||
| line-height: 1.5; | |||||
| font-weight: 500; | |||||
| color: var(--brand-black); | |||||
| transition: opacity 0.1s; | |||||
| background-color: white; | |||||
| padding: 10px 0; | |||||
| } | |||||
| .details { | |||||
| margin: 0px; | |||||
| font-size: 0.9rem; | |||||
| line-height: 1.5; | |||||
| font-weight: 400; | |||||
| color: var(--light-grey); | |||||
| overflow: hidden; | |||||
| transition: opacity 0.1s; | |||||
| } | |||||
| .action-buttons { | |||||
| display: flex; | |||||
| padding: 0 3%; | |||||
| z-index: 1; | |||||
| margin: 0 auto 20px; | |||||
| width: 90%; | |||||
| background-color: white; | |||||
| border-radius: 10px; | |||||
| position: sticky; | |||||
| position: -webkit-sticky; | |||||
| bottom: 10px; | |||||
| z-index: 2; | |||||
| box-shadow: 0px 0px 15px rgba(var(--light-grey-rgb), 0.3); | |||||
| justify-content: center; | |||||
| height: 60px; | |||||
| .shortcuts { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| height: 100%; | |||||
| width: 50%; | |||||
| button { | |||||
| margin-right: 5px; | |||||
| border-radius: 50%; | |||||
| background-color: rgba(var(--light-grey-rgb), 0.1); | |||||
| margin: 0 auto; | |||||
| width: 40px; | |||||
| height: 40px; | |||||
| &.wide-button { | |||||
| width: auto; | |||||
| border-radius: 5px; | |||||
| padding: 0 10px; | |||||
| } | |||||
| &.active { | |||||
| ion-icon, span { | |||||
| color: var(--brand-red); | |||||
| } | |||||
| } | |||||
| span { | |||||
| vertical-align: middle; | |||||
| color: var(--light-grey); | |||||
| } | |||||
| ion-icon { | |||||
| vertical-align: middle; | |||||
| color: var(--brand-black); | |||||
| font-size: 1.2rem; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| .comments { | |||||
| background-color: white; | |||||
| width: 90%; | |||||
| position: relative; | |||||
| box-shadow: 0px 0px 0px var(--light-grey); | |||||
| z-index: 1; | |||||
| margin: -20px auto 20px; | |||||
| border-radius: 10px; | |||||
| box-shadow: 0px 0px 15px rgba(var(--light-grey-rgb), 0.3); | |||||
| border-radius: 10px; | |||||
| overflow: hidden; | |||||
| opacity: 0; | |||||
| animation: fadeInFromBottom 0.5s forwards; | |||||
| header { | |||||
| font-size: 1.1rem; | |||||
| margin: 0px; | |||||
| line-height: 1.5; | |||||
| font-weight: 500; | |||||
| color: var(--brand-black); | |||||
| transition: opacity 0.1s; | |||||
| background-color: white; | |||||
| padding: 10px 5%; | |||||
| } | |||||
| ul { | |||||
| list-style: none; | |||||
| padding: 0; | |||||
| margin: 0; | |||||
| li { | |||||
| padding: 5px 5% 10px; | |||||
| border-top: 1px solid rgba(var(--light-grey-rgb), 0.3); | |||||
| line-height: 1.5; | |||||
| } | |||||
| label { | |||||
| font-size: 1rem; | |||||
| font-weight: 500; | |||||
| letter-spacing: 1px; | |||||
| color: rgba(var(--brand-red-rgb), 0.8); | |||||
| } | |||||
| p { | |||||
| margin: 3px 0; | |||||
| font-size: 1rem; | |||||
| font-weight: 400; | |||||
| color: var(--light-grey); | |||||
| } | |||||
| button { | |||||
| background-color: #f3f3f3; | |||||
| margin-right: 5px; | |||||
| height: 30px; | |||||
| width: auto; | |||||
| border-radius: 5px; | |||||
| padding: 0 5px; | |||||
| span { | |||||
| vertical-align: middle; | |||||
| color: var(--light-grey); | |||||
| } | |||||
| ion-icon { | |||||
| vertical-align: middle; | |||||
| color: var(--brand-black); | |||||
| font-size: 1rem; | |||||
| } | |||||
| &.active { | |||||
| ion-icon, span { | |||||
| color: var(--brand-red); | |||||
| } | |||||
| } | |||||
| } | |||||
| .input-holder { | |||||
| display: flex; | |||||
| width: 100%; | |||||
| height: 70px; | |||||
| align-items: center; | |||||
| input { | |||||
| width: calc(100% - 80px); | |||||
| margin: 0 auto; | |||||
| border: 1px solid rgba(var(--light-grey-rgb), 0.3); | |||||
| border-radius: 30px; | |||||
| font-size: 14px; | |||||
| color: var(--brand-black); | |||||
| font-weight: 500; | |||||
| height: 40px; | |||||
| padding: 0 15px; | |||||
| } | |||||
| button { | |||||
| width: 40px; | |||||
| height: 40px; | |||||
| background-color: var(--brand-red); | |||||
| margin: 0 auto; | |||||
| border-radius: 50%; | |||||
| ion-icon { | |||||
| color: white; | |||||
| font-size: 16px; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,24 @@ | |||||
| import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { IonicModule } from '@ionic/angular'; | |||||
| import { HomeDetailsPage } from './home-details.page'; | |||||
| describe('HomeDetailsPage', () => { | |||||
| let component: HomeDetailsPage; | |||||
| let fixture: ComponentFixture<HomeDetailsPage>; | |||||
| beforeEach(async(() => { | |||||
| TestBed.configureTestingModule({ | |||||
| declarations: [ HomeDetailsPage ], | |||||
| imports: [IonicModule.forRoot()] | |||||
| }).compileComponents(); | |||||
| fixture = TestBed.createComponent(HomeDetailsPage); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| })); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,43 @@ | |||||
| import { Component, OnInit } from '@angular/core'; | |||||
| import { ActivatedRoute } from '@angular/router'; | |||||
| import { Location } from '@angular/common'; | |||||
| import { INews } from '../home/home.page'; | |||||
| @Component({ | |||||
| selector: 'app-home-details', | |||||
| templateUrl: './home-details.page.html', | |||||
| styleUrls: ['./home-details.page.scss'], | |||||
| }) | |||||
| export class HomeDetailsPage implements OnInit { | |||||
| newsDetails: INews; | |||||
| myComment: string = ''; | |||||
| constructor( | |||||
| private route: ActivatedRoute, | |||||
| private location: Location | |||||
| ) { } | |||||
| ngOnInit() { | |||||
| this.newsDetails = JSON.parse(this.route.snapshot.paramMap.get('news')); | |||||
| } | |||||
| back() { | |||||
| this.location.back(); | |||||
| } | |||||
| postComment() { | |||||
| this.newsDetails.comments.push({ | |||||
| user: 'Test', | |||||
| comment: this.myComment, | |||||
| isLiked: false, | |||||
| likes: 0, | |||||
| }); | |||||
| this.myComment = ''; | |||||
| } | |||||
| scrollToAddComment() { | |||||
| document.querySelector('#comment-input').scrollIntoView({behavior: "smooth", block: "start"}); | |||||
| } | |||||
| } | |||||
| @@ -14,14 +14,7 @@ | |||||
| </section> | </section> | ||||
| </div> | </div> | ||||
| <button (click)="closeArticle()" | |||||
| class="close-article-button" | |||||
| [ngClass]="{'active' : selectedArticle !== null }"> | |||||
| <ion-icon name="close"></ion-icon> | |||||
| </button> | |||||
| <ion-slides [options]="slideOpts" *ngIf="selectedTab === 'news'" | |||||
| [ngClass]="{'active' : selectedArticle !== null}" #slides> | |||||
| <ion-slides [options]="slideOpts" *ngIf="selectedTab === 'news'" #slides> | |||||
| <ion-slide *ngFor="let news of newsData; let i = index"> | <ion-slide *ngFor="let news of newsData; let i = index"> | ||||
| <div class="image-holder"> | <div class="image-holder"> | ||||
| @@ -29,9 +22,7 @@ | |||||
| <img [src]="news.image"> | <img [src]="news.image"> | ||||
| </figure> | </figure> | ||||
| <button | |||||
| [ngClass]="{'active' : selectedArticle !== null}" | |||||
| *ngIf="news.type === 'VIDEO'"> | |||||
| <button *ngIf="news.type === 'VIDEO'"> | |||||
| <ion-icon name="play"></ion-icon> | <ion-icon name="play"></ion-icon> | ||||
| </button> | </button> | ||||
| @@ -48,28 +39,7 @@ | |||||
| <div class="details"> | <div class="details"> | ||||
| {{ news.description }} | {{ news.description }} | ||||
| </div> | </div> | ||||
| </section> | |||||
| <section class="comments" *ngIf="selectedArticle !== null"> | |||||
| <header> Comments </header> | |||||
| <ul> | |||||
| <li *ngFor="let comment of news.comments"> | |||||
| <p> {{ comment.comment }} <label> - {{ comment.user }} </label> </p> | |||||
| <button (click)="comment.isLiked = !comment.isLiked" | |||||
| [ngClass]="{'active' : comment.isLiked}"> | |||||
| <ion-icon *ngIf="!comment.isLiked" name="heart-outline"></ion-icon> | |||||
| <ion-icon *ngIf="comment.isLiked" name="heart"></ion-icon> | |||||
| <span> {{ comment.isLiked ? comment.likes + 1 : comment.likes }} </span> | |||||
| </button> | |||||
| </li> | |||||
| <div class="input-holder" id="comment-input"> | |||||
| <input type="text" placeholder="Type your comment" [(ngModel)]="myComment"> | |||||
| <button (click)="postComment()"> <ion-icon name="send"></ion-icon> </button> | |||||
| </div> | |||||
| </ul> | |||||
| </section> | |||||
| </section> | |||||
| <section class="action-buttons"> | <section class="action-buttons"> | ||||
| <section class="shortcuts"> | <section class="shortcuts"> | ||||
| @@ -83,22 +53,9 @@ | |||||
| <button> | <button> | ||||
| <ion-icon name="share-social-outline"></ion-icon> | <ion-icon name="share-social-outline"></ion-icon> | ||||
| </button> | </button> | ||||
| </section> | |||||
| <section class="shortcuts" *ngIf="selectedArticle !== null"> | |||||
| <button (click)="news.isBookmarked = !news.isBookmarked" | |||||
| [ngClass]="{'active' : news.isBookmarked}"> | |||||
| <ion-icon *ngIf="!news.isBookmarked" name="bookmark-outline"></ion-icon> | |||||
| <ion-icon *ngIf="news.isBookmarked" name="bookmark"></ion-icon> | |||||
| </button> | |||||
| <button class="wide-button" (click)="scrollToAddComment()"> | |||||
| <ion-icon name="chatbubble-outline"></ion-icon> | |||||
| <span> {{ news.comments.length }} </span> | |||||
| </button> | |||||
| </section> | |||||
| </section> | |||||
| <button class="read-more" (click)="expandArticle(i)"> | |||||
| <button class="read-more" (click)="showNewsDetails(news)"> | |||||
| <span> More </span> | <span> More </span> | ||||
| <ion-icon name="chevron-forward-outline"></ion-icon> | <ion-icon name="chevron-forward-outline"></ion-icon> | ||||
| </button> | </button> | ||||
| @@ -3,10 +3,7 @@ ion-content { | |||||
| } | } | ||||
| .heading-holder { | .heading-holder { | ||||
| position: fixed; | |||||
| top: 0; | |||||
| left: 0; | |||||
| width: 100%; | |||||
| margin-bottom: 3rem; | |||||
| } | } | ||||
| .main-header { | .main-header { | ||||
| @@ -55,126 +52,15 @@ ion-content { | |||||
| } | } | ||||
| } | } | ||||
| .close-article-button { | |||||
| width: 40px; | |||||
| height: 40px; | |||||
| position: fixed; | |||||
| top: 10px; | |||||
| right: 10px; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| background-color: rgba(#ffff, 0.5); | |||||
| border-radius: 50%; | |||||
| z-index: 3; | |||||
| opacity: 0; | |||||
| transform: translateY(10px); | |||||
| pointer-events: none; | |||||
| transition: opacity 0.3s, transform 0.3s; | |||||
| &.active { | |||||
| opacity: 1; | |||||
| transition-delay: 1s; | |||||
| transform: translateY(0px); | |||||
| pointer-events: all; | |||||
| } | |||||
| ion-icon { | |||||
| color: white; | |||||
| font-size: 20px; | |||||
| } | |||||
| } | |||||
| ion-slides { | ion-slides { | ||||
| margin-top: 40%; | |||||
| height: calc(100vh - 40%); | |||||
| height: calc(100vh - 40% - 16px); | |||||
| padding: 8px 0; | |||||
| position: relative; | position: relative; | ||||
| left: 0; | left: 0; | ||||
| top: 0; | top: 0; | ||||
| transition: transform 0.5s, height 0.3s, margin 0.3s, width 0.3s; | |||||
| z-index: 1; | z-index: 1; | ||||
| &.active { | |||||
| margin: 0px; | |||||
| width: 100%; | |||||
| transform: translate(0, 0%); | |||||
| height: calc(100vh - 56px); | |||||
| ion-slide { | |||||
| background-color: white; | |||||
| border-radius: 0px; | |||||
| overflow: auto; | |||||
| .content { | |||||
| width: 90%; | |||||
| height: auto; | |||||
| background-color: white; | |||||
| transform: translateY(-30px); | |||||
| position: relative; | |||||
| border-radius: 10px; | |||||
| transition-delay: 0.3s; | |||||
| overflow: auto; | |||||
| border-width: 0px; | |||||
| box-shadow: 0px 0px 15px rgba(var(--light-grey-rgb), 0.3); | |||||
| h4, .details { | |||||
| opacity: 0; | |||||
| animation: showUpContent 0.3s forwards; | |||||
| animation-delay: 0.3s; | |||||
| } | |||||
| } | |||||
| .action-buttons { | |||||
| width: 90%; | |||||
| background-color: white; | |||||
| border-radius: 10px; | |||||
| position: sticky; | |||||
| position: -webkit-sticky; | |||||
| bottom: 0; | |||||
| z-index: 2; | |||||
| box-shadow: 0px 0px 15px rgba(var(--light-grey-rgb), 0.3); | |||||
| justify-content: center; | |||||
| height: 60px; | |||||
| .shortcuts { | |||||
| width: 50%; | |||||
| button { | |||||
| background-color: rgba(var(--light-grey-rgb), 0.1); | |||||
| margin: 0 auto; | |||||
| width: 40px; | |||||
| height: 40px; | |||||
| &.wide-button { | |||||
| width: auto; | |||||
| padding: 0 10px; | |||||
| } | |||||
| } | |||||
| } | |||||
| .read-more { | |||||
| display: none; | |||||
| } | |||||
| } | |||||
| .image-holder figure { | |||||
| filter: brightness(30%); | |||||
| } | |||||
| } | |||||
| } | |||||
| @keyframes showUpContent { | |||||
| 0% { | |||||
| opacity: 0; | |||||
| transform: translateY(20px); | |||||
| -webkit-line-clamp: 4; | |||||
| } | |||||
| 100% { | |||||
| opacity: 1; | |||||
| -webkit-line-clamp: unset; | |||||
| transform: translateY(0px); | |||||
| } | |||||
| } | |||||
| overflow: hidden; | |||||
| ion-slide { | ion-slide { | ||||
| display: block; | display: block; | ||||
| @@ -183,13 +69,11 @@ ion-slides { | |||||
| text-align: left; | text-align: left; | ||||
| align-self: start; | align-self: start; | ||||
| height: 100%; | height: 100%; | ||||
| transition: width 0.5s, transform 0.3s, margin 0.3s; | |||||
| box-shadow: 2px 2px 5px black; | |||||
| } | } | ||||
| .image-holder { | .image-holder { | ||||
| position: sticky; | |||||
| position: -webkit-sticky; | |||||
| top: 0; | |||||
| position: relative; | |||||
| height: 40%; | height: 40%; | ||||
| overflow: hidden; | overflow: hidden; | ||||
| @@ -211,30 +95,6 @@ ion-slides { | |||||
| pointer-events: none; | pointer-events: none; | ||||
| } | } | ||||
| &.active { | |||||
| transform: translate(calc(-50vw + 40px), -15vh); | |||||
| animation: ripple 1s infinite; | |||||
| background-color: rgba(var(--brand-red-rgb), 0.5); | |||||
| ion-icon { | |||||
| color: white; | |||||
| } | |||||
| } | |||||
| @keyframes ripple { | |||||
| 0% { | |||||
| box-shadow: 0px 0px 0px var(--brand-red); | |||||
| } | |||||
| 50% { | |||||
| box-shadow: 0px 0px 5px var(--brand-red); | |||||
| } | |||||
| 100% { | |||||
| box-shadow: 0px 0px 0px var(--brand-red); | |||||
| } | |||||
| } | |||||
| ion-icon { | ion-icon { | ||||
| color: white; | color: white; | ||||
| font-size: 20px; | font-size: 20px; | ||||
| @@ -377,114 +237,4 @@ ion-slides { | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| .comments { | |||||
| background-color: white; | |||||
| width: 90%; | |||||
| position: relative; | |||||
| box-shadow: 0px 0px 0px var(--light-grey); | |||||
| z-index: 1; | |||||
| margin: 0px auto 20px; | |||||
| border-radius: 10px; | |||||
| box-shadow: 0px 0px 15px rgba(var(--light-grey-rgb), 0.3); | |||||
| border-radius: 10px; | |||||
| overflow: hidden; | |||||
| header { | |||||
| font-size: 1.1rem; | |||||
| margin: 0px; | |||||
| line-height: 1.5; | |||||
| font-weight: 500; | |||||
| color: var(--brand-black); | |||||
| transition: opacity 0.1s; | |||||
| background-color: white; | |||||
| padding: 10px 5%; | |||||
| } | |||||
| ul { | |||||
| list-style: none; | |||||
| padding: 0; | |||||
| margin: 0; | |||||
| li { | |||||
| padding: 5px 5% 10px; | |||||
| border-top: 1px solid rgba(var(--light-grey-rgb), 0.3); | |||||
| line-height: 1.5; | |||||
| } | |||||
| label { | |||||
| font-size: 1rem; | |||||
| font-weight: 500; | |||||
| letter-spacing: 1px; | |||||
| color: rgba(var(--brand-red-rgb), 0.8); | |||||
| } | |||||
| p { | |||||
| margin: 3px 0; | |||||
| font-size: 1rem; | |||||
| font-weight: 400; | |||||
| color: var(--light-grey); | |||||
| } | |||||
| button { | |||||
| background-color: #f3f3f3; | |||||
| margin-right: 5px; | |||||
| height: 30px; | |||||
| width: auto; | |||||
| border-radius: 5px; | |||||
| padding: 0 5px; | |||||
| span { | |||||
| vertical-align: middle; | |||||
| color: var(--light-grey); | |||||
| } | |||||
| ion-icon { | |||||
| vertical-align: middle; | |||||
| color: var(--brand-black); | |||||
| font-size: 1rem; | |||||
| } | |||||
| &.active { | |||||
| ion-icon, span { | |||||
| color: var(--brand-red); | |||||
| } | |||||
| } | |||||
| } | |||||
| .input-holder { | |||||
| display: flex; | |||||
| width: 100%; | |||||
| height: 70px; | |||||
| align-items: center; | |||||
| input { | |||||
| width: calc(100% - 80px); | |||||
| margin: 0 auto; | |||||
| border: 1px solid rgba(var(--light-grey-rgb), 0.3); | |||||
| border-radius: 30px; | |||||
| font-size: 14px; | |||||
| color: var(--brand-black); | |||||
| font-weight: 500; | |||||
| height: 40px; | |||||
| padding: 0 15px; | |||||
| } | |||||
| button { | |||||
| width: 40px; | |||||
| height: 40px; | |||||
| background-color: var(--brand-red); | |||||
| margin: 0 auto; | |||||
| border-radius: 50%; | |||||
| ion-icon { | |||||
| color: white; | |||||
| font-size: 16px; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| @@ -1,38 +1,43 @@ | |||||
| import { Component, OnInit, ViewChild } from '@angular/core'; | import { Component, OnInit, ViewChild } from '@angular/core'; | ||||
| import { IonSlides } from '@ionic/angular'; | import { IonSlides } from '@ionic/angular'; | ||||
| import { Router } from '@angular/router'; | |||||
| export type INews = { | |||||
| id: string | number, | |||||
| image: string, | |||||
| heading: string, | |||||
| description: string, | |||||
| type: 'VIDEO' | 'ARTICLE', | |||||
| likes: number, | |||||
| isBookmarked: boolean, | |||||
| isLiked: boolean, | |||||
| comments: Array<{ | |||||
| user: string, | |||||
| comment: string, | |||||
| likes: number, | |||||
| isLiked: boolean | |||||
| }>, | |||||
| }; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-home', | selector: 'app-home', | ||||
| templateUrl: './home.page.html', | templateUrl: './home.page.html', | ||||
| styleUrls: ['./home.page.scss'], | styleUrls: ['./home.page.scss'], | ||||
| }) | }) | ||||
| export class HomePage implements OnInit { | export class HomePage implements OnInit { | ||||
| @ViewChild('slides', {static: false}) slides: IonSlides; | @ViewChild('slides', {static: false}) slides: IonSlides; | ||||
| selectedTab: string = 'news'; | selectedTab: string = 'news'; | ||||
| selectedArticle: number = null; | |||||
| myComment: string = ''; | |||||
| selectedArticle: number = null; | |||||
| slideOpts = { }; | slideOpts = { }; | ||||
| newsData: Array<{ | |||||
| id: string | number, | |||||
| image: string, | |||||
| heading: string, | |||||
| description: string, | |||||
| type: 'VIDEO' | 'ARTICLE', | |||||
| likes: number, | |||||
| isBookmarked: boolean, | |||||
| isLiked: boolean, | |||||
| comments: Array<{ | |||||
| user: string, | |||||
| comment: string, | |||||
| likes: number, | |||||
| isLiked: boolean | |||||
| }>, | |||||
| }> = []; | |||||
| constructor() { } | |||||
| newsData: Array<INews> = []; | |||||
| constructor( | |||||
| private router: Router | |||||
| ) { } | |||||
| ngOnInit() { | ngOnInit() { | ||||
| @@ -94,9 +99,13 @@ export class HomePage implements OnInit { | |||||
| slidesOffsetAfter: 0, | slidesOffsetAfter: 0, | ||||
| }; | }; | ||||
| setTimeout(() => { | |||||
| this.slides.slideTo(index); | |||||
| }, 200); | |||||
| // setTimeout(() => { | |||||
| // this.slides.slideTo(index); | |||||
| // }, 200); | |||||
| } | |||||
| showNewsDetails(news: any) { | |||||
| this.router.navigate(['/home-details', { news: JSON.stringify(news) }]) | |||||
| } | } | ||||
| closeArticle() { | closeArticle() { | ||||
| @@ -109,20 +118,4 @@ export class HomePage implements OnInit { | |||||
| slidesOffsetAfter: 30, | slidesOffsetAfter: 30, | ||||
| }; | }; | ||||
| } | } | ||||
| postComment() { | |||||
| this.newsData[this.selectedArticle].comments.push({ | |||||
| user: 'Test', | |||||
| comment: this.myComment, | |||||
| isLiked: false, | |||||
| likes: 0, | |||||
| }); | |||||
| this.myComment = ''; | |||||
| } | |||||
| scrollToAddComment() { | |||||
| document.querySelector('#comment-input').scrollIntoView({behavior: "smooth", block: "start"}); | |||||
| } | |||||
| } | } | ||||