feat: add likes page
This commit is contained in:
parent
a88d3899a4
commit
a590e4c7d4
@ -71,6 +71,18 @@ export default class ImageRouter extends AppRouter {
|
|||||||
|
|
||||||
return (await page.apply(cursor.sort({ created: -1 })).toArray()).map(v => ImageRouter.deserialize(v, jwt?.name));
|
return (await page.apply(cursor.sort({ created: -1 })).toArray()).map(v => ImageRouter.deserialize(v, jwt?.name));
|
||||||
}
|
}
|
||||||
|
@rest('GET', '/likes/:username')
|
||||||
|
async likeFeed(username: string, @page() page: Page, @jwt('salt', false) @auth() jwt?: JWTPayload) {
|
||||||
|
const user = await this.db.users.findOne({ username });
|
||||||
|
if (user === undefined) throw new HttpError("User not found.");
|
||||||
|
|
||||||
|
const cursor = this.db.images.find({ $or: [
|
||||||
|
{ _id: { $in: user.likes }, visibility: Visibility.Public, },
|
||||||
|
{ _id: { $in: user.likes }, author: user.username, }
|
||||||
|
] });
|
||||||
|
|
||||||
|
return (await page.apply(cursor.sort({ created: -1 })).toArray()).map(v => ImageRouter.deserialize(v, jwt?.name));
|
||||||
|
}
|
||||||
|
|
||||||
@rest('POST', '/upload')
|
@rest('POST', '/upload')
|
||||||
async upload(@body() body: Blob, @headers() headers: Headers, @jwt(v => v.salt, true) @auth() jwt: JWTPayload) {
|
async upload(@body() body: Blob, @headers() headers: Headers, @jwt(v => v.salt, true) @auth() jwt: JWTPayload) {
|
||||||
@ -172,7 +184,7 @@ export default class ImageRouter extends AppRouter {
|
|||||||
if (!user) throw new HttpError("You don't exist.");
|
if (!user) throw new HttpError("You don't exist.");
|
||||||
|
|
||||||
const res = await this.db.images.updateOne(
|
const res = await this.db.images.updateOne(
|
||||||
{ _id: id },
|
{ _id: id, visibility: { $not: { $eq: Visibility.Private } } },
|
||||||
{ $addToSet: { likes: jwt.name } }
|
{ $addToSet: { likes: jwt.name } }
|
||||||
);
|
);
|
||||||
if (res.matchedCount === 0) throw new HttpError("Image doesn't exist.");
|
if (res.matchedCount === 0) throw new HttpError("Image doesn't exist.");
|
||||||
@ -190,7 +202,7 @@ export default class ImageRouter extends AppRouter {
|
|||||||
if (!user) throw new HttpError("You don't exist.");
|
if (!user) throw new HttpError("You don't exist.");
|
||||||
|
|
||||||
const res = await this.db.images.updateOne(
|
const res = await this.db.images.updateOne(
|
||||||
{ _id: id },
|
{ _id: id, visibility: { $not: { $eq: Visibility.Private } } },
|
||||||
{ $pull: { likes: jwt.name } }
|
{ $pull: { likes: jwt.name } }
|
||||||
);
|
);
|
||||||
if (res.matchedCount === 0) throw new HttpError("Image doesn't exist.");
|
if (res.matchedCount === 0) throw new HttpError("Image doesn't exist.");
|
||||||
|
@ -6,6 +6,7 @@ import { PageSignupComponent } from './page-signup/page-signup.component';
|
|||||||
import { PageUploadComponent } from './page-upload/page-upload.component';
|
import { PageUploadComponent } from './page-upload/page-upload.component';
|
||||||
import { PageUserComponent } from './page-user/page-user.component';
|
import { PageUserComponent } from './page-user/page-user.component';
|
||||||
import { PageImageComponent } from './page-image/page-image.component';
|
import { PageImageComponent } from './page-image/page-image.component';
|
||||||
|
import { PageLikesComponent } from './page-likes/page-likes.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: '', component: PageHomeComponent },
|
{ path: '', component: PageHomeComponent },
|
||||||
@ -13,6 +14,7 @@ const routes: Routes = [
|
|||||||
{ path: 'signup', component: PageSignupComponent },
|
{ path: 'signup', component: PageSignupComponent },
|
||||||
{ path: 'upload', component: PageUploadComponent },
|
{ path: 'upload', component: PageUploadComponent },
|
||||||
{ path: 'user/:name', component: PageUserComponent },
|
{ path: 'user/:name', component: PageUserComponent },
|
||||||
|
{ path: 'likes/:name', component: PageLikesComponent },
|
||||||
{ path: 'image/:id', component: PageImageComponent },
|
{ path: 'image/:id', component: PageImageComponent },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import { MessageComponent } from './message/message.component';
|
|||||||
import { PageImageComponent } from './page-image/page-image.component';
|
import { PageImageComponent } from './page-image/page-image.component';
|
||||||
import { SecurePipe } from './secure.pipe';
|
import { SecurePipe } from './secure.pipe';
|
||||||
import { AuthorizerInterceptor } from './authorizer.interceptor';
|
import { AuthorizerInterceptor } from './authorizer.interceptor';
|
||||||
|
import { PageLikesComponent } from './page-likes/page-likes.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -25,6 +26,7 @@ import { AuthorizerInterceptor } from './authorizer.interceptor';
|
|||||||
PageSignupComponent,
|
PageSignupComponent,
|
||||||
PageUploadComponent,
|
PageUploadComponent,
|
||||||
PageUserComponent,
|
PageUserComponent,
|
||||||
|
PageLikesComponent,
|
||||||
ImagesComponent,
|
ImagesComponent,
|
||||||
ImageComponent,
|
ImageComponent,
|
||||||
MessageComponent,
|
MessageComponent,
|
||||||
|
4
frontend/src/app/page-likes/page-likes.component.html
Normal file
4
frontend/src/app/page-likes/page-likes.component.html
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<h1 style="text-align: center;">User {{user.username}}'s likes:</h1>
|
||||||
|
<a style="text-align: center;" href="/user/{{user.username}}">Go to posts</a>
|
||||||
|
|
||||||
|
<app-images [images]="images | async" #imgs></app-images>
|
40
frontend/src/app/page-likes/page-likes.component.ts
Normal file
40
frontend/src/app/page-likes/page-likes.component.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { AfterViewInit, Component, ViewChild } from '@angular/core';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { User, UsersService } from '../services/users.service';
|
||||||
|
import { Image, ImagesService } from '../services/images.service';
|
||||||
|
import { ImagesComponent } from '../images/images.component';
|
||||||
|
import { ScrollService } from '../services/scroll.service';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { MessagesService } from '../services/messages.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-page-likes',
|
||||||
|
templateUrl: './page-likes.component.html',
|
||||||
|
styleUrls: ['./page-likes.component.scss']
|
||||||
|
})
|
||||||
|
export class PageLikesComponent {
|
||||||
|
@ViewChild("imgs")
|
||||||
|
public imagesEl!: ImagesComponent;
|
||||||
|
public images!: Observable<Image[]>;
|
||||||
|
public user: User = { username: 'Loading...' };
|
||||||
|
|
||||||
|
public feed(n: number, i: number) {
|
||||||
|
return this._images.likesFeed(this.user.username, { n, i });
|
||||||
|
}
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
route: ActivatedRoute,
|
||||||
|
users: UsersService,
|
||||||
|
private _images: ImagesService,
|
||||||
|
private _scroll: ScrollService,
|
||||||
|
private msgs: MessagesService,
|
||||||
|
) {
|
||||||
|
route.paramMap.subscribe(async v => {
|
||||||
|
try {
|
||||||
|
this.user = await users.get(v.get('name')!);
|
||||||
|
this.images = ImagesComponent.fromFeed(this._scroll.scrollHost!, 10, this.feed.bind(this));
|
||||||
|
}
|
||||||
|
catch (e: any) { msgs.error(e); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
<h1 style="text-align: center;">User {{user.username}}</h1>
|
<h1 style="text-align: center;">User {{user.username}}'s posts:</h1>
|
||||||
|
<a style="text-align: center;" href="/likes/{{user.username}}">Go to likes</a>
|
||||||
|
|
||||||
<app-images [images]="images | async" #imgs></app-images>
|
<app-images [images]="images | async" #imgs></app-images>
|
||||||
|
@ -47,6 +47,11 @@ export class ImagesService {
|
|||||||
this.users.httpOptions({ params: page })
|
this.users.httpOptions({ params: page })
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
public async likesFeed(username: string, page: Page = {}) {
|
||||||
|
return await firstValueFrom(this.http.get<Image[]>(`${this.url}/likes/${username}`,
|
||||||
|
this.users.httpOptions({ params: page })
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
public async upload(proto: CreateImageBody, file: File) {
|
public async upload(proto: CreateImageBody, file: File) {
|
||||||
const data = new FormData();
|
const data = new FormData();
|
||||||
|
Loading…
Reference in New Issue
Block a user