From a7100ae8a21083480a06f0d40ab288022e03b0eb Mon Sep 17 00:00:00 2001 From: Jordi <55429631+jorbush@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:23:20 +0100 Subject: [PATCH] user photo service --- .../controller/UserController.java | 4 +- .../postrifybackend/service/UserService.java | 4 +- .../app/components/header/header.component.ts | 19 ++++++-- .../src/app/components/home/home.component.ts | 25 ++++++----- .../post-detail/post-detail.component.ts | 21 +++++++++ .../settings-modal.component.spec.ts | 9 +++- .../settings-modal.component.ts | 43 +++++++++++++++---- .../src/app/services/user-image.service.ts | 14 ++++++ 8 files changed, 112 insertions(+), 27 deletions(-) create mode 100644 postrify-frontend/src/app/services/user-image.service.ts diff --git a/postrify-backend/src/main/java/com/postrify/postrifybackend/controller/UserController.java b/postrify-backend/src/main/java/com/postrify/postrifybackend/controller/UserController.java index df823e7..dfe774b 100644 --- a/postrify-backend/src/main/java/com/postrify/postrifybackend/controller/UserController.java +++ b/postrify-backend/src/main/java/com/postrify/postrifybackend/controller/UserController.java @@ -17,14 +17,14 @@ public class UserController { @Autowired private UserService userService; @GetMapping("/{username}/image") - public ResponseEntity getUserImage(@PathVariable String username) { + public ResponseEntity getUserImage(@PathVariable final String username) { String base64Image = userService.getUserImage(username); return ResponseEntity.ok(base64Image); } @PutMapping("/{username}/image") public ResponseEntity updateUserImage( - @PathVariable String username, @RequestBody String base64Image) { + @PathVariable final String username, @RequestBody final String base64Image) { userService.updateUserImage(username, base64Image); return ResponseEntity.ok("User image updated successfully!"); } diff --git a/postrify-backend/src/main/java/com/postrify/postrifybackend/service/UserService.java b/postrify-backend/src/main/java/com/postrify/postrifybackend/service/UserService.java index cbebc94..954a755 100644 --- a/postrify-backend/src/main/java/com/postrify/postrifybackend/service/UserService.java +++ b/postrify-backend/src/main/java/com/postrify/postrifybackend/service/UserService.java @@ -29,12 +29,12 @@ public User registerUser(final User user) { return userRepository.save(user); } - public String getUserImage(String username) { + public String getUserImage(final String username) { User user = findByUsername(username); return user.getImage(); } - public void updateUserImage(String username, String base64Image) { + public void updateUserImage(final String username, final String base64Image) { User user = findByUsername(username); user.setImage(base64Image); userRepository.save(user); diff --git a/postrify-frontend/src/app/components/header/header.component.ts b/postrify-frontend/src/app/components/header/header.component.ts index e416cad..913c1b4 100644 --- a/postrify-frontend/src/app/components/header/header.component.ts +++ b/postrify-frontend/src/app/components/header/header.component.ts @@ -2,6 +2,8 @@ import { Component, OnInit } from '@angular/core'; import { RouterLink } from '@angular/router'; import { AuthService } from '../../services/auth.service'; import { SettingsModalComponent } from '../settings-modal/settings-modal.component'; +import { Subscription } from 'rxjs'; +import { UserImageService } from '../../services/user-image.service'; @Component({ selector: 'app-header', @@ -129,7 +131,9 @@ import { SettingsModalComponent } from '../settings-modal/settings-modal.compone @if (isSettingsOpen) { - + } `, styles: [ @@ -229,7 +233,7 @@ import { SettingsModalComponent } from '../settings-modal/settings-modal.compone } } - @media (max-width: 400px) { + @media (max-width: 450px) { .username { display: none; } @@ -249,6 +253,8 @@ import { SettingsModalComponent } from '../settings-modal/settings-modal.compone ], }) export class HeaderComponent implements OnInit { + private imageUpdateSubscription: Subscription | undefined; + isDarkMode = false; logoSrc = 'assets/logo-light.png'; isAuthenticated = false; @@ -256,12 +262,19 @@ export class HeaderComponent implements OnInit { userImage: string | null = null; isSettingsOpen = false; - constructor(public authService: AuthService) {} + constructor( + public authService: AuthService, + private userImageService: UserImageService, + ) {} ngOnInit() { this.loadDarkModePreference(); this.updateLogo(); this.checkAuthentication(); + this.imageUpdateSubscription = + this.userImageService.imageUpdated$.subscribe(() => { + this.checkAuthentication(); + }); } toggleDarkMode() { diff --git a/postrify-frontend/src/app/components/home/home.component.ts b/postrify-frontend/src/app/components/home/home.component.ts index d6d7585..edfb6fa 100644 --- a/postrify-frontend/src/app/components/home/home.component.ts +++ b/postrify-frontend/src/app/components/home/home.component.ts @@ -1,10 +1,12 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, OnDestroy } from '@angular/core'; import { PostResponseDTO } from '../../models/post-response.model'; import { PostService } from '../../services/post.service'; import { Router } from '@angular/router'; import { AuthService } from '../../services/auth.service'; import { CommonModule } from '@angular/common'; import { Page } from '../../models/page.model'; +import { Subscription } from 'rxjs'; +import { UserImageService } from '../../services/user-image.service'; @Component({ selector: 'app-home', @@ -199,7 +201,9 @@ import { Page } from '../../models/page.model'; } `, }) -export class HomeComponent implements OnInit { +export class HomeComponent implements OnInit, OnDestroy { + private imageUpdateSubscription: Subscription | undefined; + posts: PostResponseDTO[] = []; isLogged = false; currentPage = 0; @@ -211,11 +215,16 @@ export class HomeComponent implements OnInit { private postService: PostService, private router: Router, private authService: AuthService, + private userImageService: UserImageService, ) {} ngOnInit(): void { this.fetchPosts(this.currentPage, this.pageSize); this.isLogged = this.authService.isAuthenticated(); + this.imageUpdateSubscription = + this.userImageService.imageUpdated$.subscribe(() => { + this.fetchPosts(this.currentPage, this.pageSize); + }); } fetchPosts(page: number, size: number): void { @@ -259,13 +268,9 @@ export class HomeComponent implements OnInit { } } - getPages(): number[] { - return Array(this.totalPages) - .fill(0) - .map((x, i) => i); - } - - trackById(index: number, post: PostResponseDTO): number { - return post.id; + ngOnDestroy(): void { + if (this.imageUpdateSubscription) { + this.imageUpdateSubscription.unsubscribe(); + } } } diff --git a/postrify-frontend/src/app/components/post-detail/post-detail.component.ts b/postrify-frontend/src/app/components/post-detail/post-detail.component.ts index d7d62e3..000fbf3 100644 --- a/postrify-frontend/src/app/components/post-detail/post-detail.component.ts +++ b/postrify-frontend/src/app/components/post-detail/post-detail.component.ts @@ -7,6 +7,8 @@ import { CommonModule } from '@angular/common'; import { ToastService } from '../../services/toast.service'; import { ReadingTimePipe } from '../../pipes/reading-time.pipe'; import { BoldTextPipe } from '../../pipes/bold-text.pipe'; +import { Subscription } from 'rxjs'; +import { UserImageService } from '../../services/user-image.service'; @Component({ selector: 'app-post-detail', @@ -242,10 +244,24 @@ import { BoldTextPipe } from '../../pipes/bold-text.pipe'; position: relative; border: 2px solid var(--border-color); } + + @media (max-width: 500px) { + .post-detail-container { + padding: 0.5rem; + } + .post-title { + font-size: 2rem; + } + .post-content { + padding: 1rem; + } + } `, ], }) export class PostDetailComponent implements OnInit { + private imageUpdateSubscription: Subscription | undefined; + post?: PostResponseDTO; isLogged = false; username?: string; @@ -256,6 +272,7 @@ export class PostDetailComponent implements OnInit { private router: Router, private authService: AuthService, private toastService: ToastService, + private userImageService: UserImageService, ) {} ngOnInit(): void { @@ -263,6 +280,10 @@ export class PostDetailComponent implements OnInit { this.fetchPost(postId); this.isLogged = this.authService.isAuthenticated(); this.username = localStorage.getItem('username') || ''; + this.imageUpdateSubscription = + this.userImageService.imageUpdated$.subscribe(() => { + this.fetchPost(postId); + }); } fetchPost(id: number): void { diff --git a/postrify-frontend/src/app/components/settings-modal/settings-modal.component.spec.ts b/postrify-frontend/src/app/components/settings-modal/settings-modal.component.spec.ts index 7ed3ef2..8dc606a 100644 --- a/postrify-frontend/src/app/components/settings-modal/settings-modal.component.spec.ts +++ b/postrify-frontend/src/app/components/settings-modal/settings-modal.component.spec.ts @@ -1,6 +1,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - import { SettingsModalComponent } from './settings-modal.component'; +import { provideHttpClientTesting } from '@angular/common/http/testing'; +import { provideHttpClient } from '@angular/common/http'; +import { ActivatedRoute } from '@angular/router'; describe('SettingsModalComponent', () => { let component: SettingsModalComponent; @@ -9,6 +11,11 @@ describe('SettingsModalComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [SettingsModalComponent], + providers: [ + provideHttpClient(), + provideHttpClientTesting(), + { provide: ActivatedRoute, useValue: {} }, + ], }).compileComponents(); fixture = TestBed.createComponent(SettingsModalComponent); diff --git a/postrify-frontend/src/app/components/settings-modal/settings-modal.component.ts b/postrify-frontend/src/app/components/settings-modal/settings-modal.component.ts index d829fbe..f6bf8c3 100644 --- a/postrify-frontend/src/app/components/settings-modal/settings-modal.component.ts +++ b/postrify-frontend/src/app/components/settings-modal/settings-modal.component.ts @@ -1,17 +1,33 @@ import { Component, OnInit, Output, EventEmitter } from '@angular/core'; import { CommonModule } from '@angular/common'; import { AuthService } from '../../services/auth.service'; +import { UserImageService } from '../../services/user-image.service'; @Component({ selector: 'app-settings-modal', standalone: true, imports: [CommonModule], template: ` -