Skip to content

Commit c873286

Browse files
committed
✨ get feed details added
1 parent 42b72c3 commit c873286

16 files changed

+321
-15
lines changed

src/app/app.module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { FeaturesModule } from './features/features.module';
88

99
@NgModule({
1010
declarations: [
11-
AppComponent
11+
AppComponent,
1212
],
1313
imports: [
1414
BrowserModule,

src/app/core/models/feed.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Website } from "./website.model";
22

33
export class Feed {
44
constructor(
5+
public _id: string,
56
public writer: string,
67
public title: string,
78
public pubDate: Date,

src/app/core/pipes/html.pipe.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Pipe, PipeTransform } from '@angular/core';
2+
import { DomSanitizer } from '@angular/platform-browser';
3+
4+
@Pipe({
5+
name: 'html'
6+
})
7+
export class HtmlPipe implements PipeTransform {
8+
constructor(
9+
private sanitizer: DomSanitizer,
10+
) {}
11+
transform(value: string, ...args: unknown[]): unknown {
12+
return this.sanitizer.bypassSecurityTrustHtml(value && value.toString());
13+
}
14+
15+
}

src/app/core/services/feed.service.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Injectable } from '@angular/core';
22
import { HttpClient } from '@angular/common/http';
33
import { environment } from 'environments/environment';
4-
import { Observable } from 'rxjs';
4+
import { map, Observable } from 'rxjs';
55

66
import { IResponseFeed } from '@interfaces/response.interface';
7+
import { Feed } from '@models/feed.model';
78

89
const base_url = environment.base_url;
910

@@ -12,11 +13,26 @@ const base_url = environment.base_url;
1213
})
1314
export class FeedService {
1415

16+
private recentFeeds: Feed[];
17+
1518
constructor(private http: HttpClient) { }
1619

20+
get getRecentsFeeds(): Feed[] {
21+
return this.recentFeeds;
22+
}
23+
24+
setRecentsFeeds(feeds: Feed[]): void {
25+
this.recentFeeds = feeds;
26+
}
27+
1728
getFeeds(skip = 0, limit = 20): Observable<IResponseFeed> {
1829
const url = `${base_url}/feed?skip=${skip}&limit=${limit}`;
1930
return this.http.get<IResponseFeed>(url);
2031
}
2132

33+
getFeed(id: string): Observable<Feed> {
34+
const url = `${base_url}/feed/${id}`;
35+
return this.http.get<IResponseFeed>(url).pipe(map((resp) => resp.feed));
36+
}
37+
2238
}

src/app/features/features.module.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import { CommonModule } from '@angular/common';
33
import { HomeComponent } from './home/home.component';
44
import { FeaturesComponent } from './features.component';
55
import { RouterModule } from '@angular/router';
6+
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
67

78
import { ComponentsModule } from '@components/components.module';
8-
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
9+
10+
import { FeedModule } from './feed/feed.module';
911

1012
@NgModule({
1113
declarations: [
@@ -16,7 +18,8 @@ import { InfiniteScrollModule } from 'ngx-infinite-scroll';
1618
CommonModule,
1719
RouterModule,
1820
ComponentsModule,
19-
InfiniteScrollModule
21+
InfiniteScrollModule,
22+
FeedModule
2023
]
2124
})
2225
export class FeaturesModule { }

src/app/features/features.routing.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ const routes: Routes = [
77
path: '',
88
component: FeaturesComponent,
99
loadChildren: () => import('./home/home.routing').then(m => m.HomeRoutingModule),
10-
}
10+
},
11+
{
12+
path: 'feed',
13+
component: FeaturesComponent,
14+
loadChildren: () => import('./feed/feed.routing').then(m => m.UsersRoutingModule),
15+
},
1116
];
1217

1318
@NgModule({

src/app/features/feed/feed.module.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { NgModule } from '@angular/core';
2+
import { CommonModule } from '@angular/common';
3+
import { FeedComponent } from './pages/feed/feed.component';
4+
import { HtmlPipe } from 'app/core/pipes/html.pipe';
5+
6+
7+
8+
@NgModule({
9+
declarations: [
10+
FeedComponent,
11+
HtmlPipe
12+
],
13+
imports: [
14+
CommonModule
15+
]
16+
})
17+
export class FeedModule { }

src/app/features/feed/feed.routing.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { NgModule } from "@angular/core";
2+
import { RouterModule, Routes } from "@angular/router";
3+
4+
import { FeedComponent } from "./pages/feed/feed.component";
5+
6+
const routes: Routes = [
7+
{
8+
path: ':feedID',
9+
component: FeedComponent
10+
}
11+
];
12+
13+
@NgModule({
14+
imports: [
15+
RouterModule.forChild(routes),
16+
],
17+
exports: [
18+
RouterModule
19+
]
20+
})
21+
export class UsersRoutingModule {}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
.feed-wrapper {
2+
display: grid;
3+
grid-template-columns: auto 300px;
4+
gap: 0.5rem;
5+
}
6+
7+
.feed-wrapper .findings {
8+
width: 300px;
9+
opacity: 1;
10+
}
11+
12+
.card.card-findings {
13+
cursor: default;
14+
opacity: 1;
15+
margin: 0;
16+
padding: 0 !important;
17+
position: fixed;
18+
width: inherit;
19+
max-width: inherit;
20+
display: flex;
21+
flex-direction: column;
22+
transform: translate(0, 9px);
23+
}
24+
25+
.banner {
26+
max-height: 20rem;
27+
width: 100%;
28+
object-fit: cover;
29+
border-radius: 10px 10px 0 0;
30+
}
31+
32+
.content {
33+
padding: 1rem;
34+
}
35+
36+
.content .title-new {
37+
font-size: 32px;
38+
font-weight: bold;
39+
}
40+
41+
.content .details {
42+
margin: 1rem 0;
43+
display: flex;
44+
align-items: center;
45+
justify-content: space-between;
46+
flex-wrap: wrap;
47+
}
48+
49+
.content .details .detail {
50+
color: var(--font-color-secondary);
51+
}
52+
53+
.content .details .bookmark {
54+
font-size: 24px;
55+
color: var(--primary-color);
56+
}
57+
58+
.content .details-website {
59+
margin-top: 1rem;
60+
display: flex;
61+
gap: 5px;
62+
flex-wrap: wrap;
63+
font-size: 18px;
64+
}
65+
66+
.content .details-website a {
67+
color: var(--primary-color);
68+
text-decoration: none;
69+
}
70+
71+
.feed {
72+
font-size: 18px;
73+
}
74+
75+
.feed img {
76+
display: none !important;
77+
}
78+
79+
.feed a {
80+
text-decoration: none;
81+
}
82+
83+
.feed ul {
84+
margin-left: 2rem;
85+
}
86+
87+
.card.card-findings .card-title {
88+
font-size: 20px;
89+
font-weight: bold;
90+
padding: 10px;
91+
}
92+
93+
.card.card-findings .item {
94+
display: flex;
95+
padding: 0.5rem 0.8rem;
96+
}
97+
98+
.card.card-findings .item:last-child {
99+
border-radius: 0 0 10px 10px;
100+
}
101+
102+
.card.card-findings .item:hover {
103+
background-color: #e1e1e1;
104+
cursor: pointer;
105+
}
106+
107+
.card.card-findings .item .item-content {
108+
flex-grow: 1;
109+
display: flex;
110+
flex-direction: column;
111+
}
112+
113+
.card.card-findings .item .item-content .title {
114+
font-size: 17px;
115+
font-weight: bold;
116+
}
117+
118+
.card.card-findings .item .item-content .writer {
119+
font-size: 12px;
120+
color: var(--font-color-secondary);
121+
flex-grow: 1;
122+
display: flex;
123+
align-items: flex-end;
124+
}
125+
126+
.card.card-findings .item figure {
127+
width: 4rem;
128+
height: 4rem;
129+
min-width: 4rem;
130+
min-height: 4rem;
131+
}
132+
133+
.card.card-findings .item figure img {
134+
object-fit: cover;
135+
width: 100%;
136+
height: 100%;
137+
border-radius: 10px;
138+
}
139+
140+
@media (max-width: 768px) {
141+
.feed-wrapper {
142+
grid-template-columns: 100%;
143+
}
144+
145+
.feed-wrapper .findings {
146+
opacity: 0;
147+
display: none;
148+
}
149+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<div class="feed-wrapper" *ngIf="feed">
2+
<div class="card news-detail">
3+
<img [src]="feed.image" class="banner" alt="">
4+
<div class="content">
5+
<span class="title-new">{{feed.title}}</span>
6+
<div class="details">
7+
<span class="detail">{{feed.writer}} &bull; {{feed.pubDate | date: 'dd/MM/yyyy, h:mm a' }}</span>
8+
<div class="bookmark">
9+
<i class="bx bx-bookmark"></i>
10+
</div>
11+
</div>
12+
<div class="feed" [innerHTML]="feed.content | html">
13+
</div>
14+
<div class="details-website">
15+
<a target="_blank" [href]="feed.link" class="original">View original new</a> &bull;
16+
<a target="_blank" [href]="feed.website.link" class="website">by {{feed.website.name}}</a>
17+
</div>
18+
</div>
19+
</div>
20+
<div class="findings">
21+
<div class="card card-findings">
22+
<span class="card-title">Recents</span>
23+
<div class="item" *ngFor="let recentFeed of recentsFeed">
24+
<div class="item-content">
25+
<span class="title">{{recentFeed.title | slice:0:35}}{{(recentFeed.title.length > 20)?'...':'' }}</span>
26+
<span class="writer">{{recentFeed.writer}}</span>
27+
</div>
28+
<figure>
29+
<img [src]="recentFeed.image" alt="new title">
30+
</figure>
31+
</div>
32+
</div>
33+
</div>
34+
</div>

0 commit comments

Comments
 (0)