From 482079fb8f9ac5a6817bc34081da8bf37019ac07 Mon Sep 17 00:00:00 2001 From: "nise.moe" Date: Sat, 9 Mar 2024 14:33:12 +0100 Subject: [PATCH] Profile page, tweaked banlist/follows --- .../nise/controller/FollowsController.kt | 1 + .../com/nisemoe/nise/service/AuthService.kt | 11 +- nise-circleguard/Dockerfile | 2 +- nise-frontend/src/app/app-routing.module.ts | 4 +- nise-frontend/src/app/app.component.css | 7 + nise-frontend/src/app/app.component.html | 9 +- nise-frontend/src/app/app.component.ts | 49 +++++-- .../src/app/banlist/banlist.component.html | 126 +++++++++++------- .../src/app/banlist/banlist.component.ts | 15 ++- .../app/contribute/contribute.component.html | 61 ++++----- .../src/app/home/home.component.html | 9 +- nise-frontend/src/app/home/home.component.ts | 28 +--- .../profile.component.css} | 0 .../profile.component.html} | 11 +- .../profile.component.ts} | 17 ++- 15 files changed, 207 insertions(+), 143 deletions(-) rename nise-frontend/src/app/{follows/follows.component.css => profile/profile.component.css} (100%) rename nise-frontend/src/app/{follows/follows.component.html => profile/profile.component.html} (58%) rename nise-frontend/src/app/{follows/follows.component.ts => profile/profile.component.ts} (66%) diff --git a/nise-backend/src/main/kotlin/com/nisemoe/nise/controller/FollowsController.kt b/nise-backend/src/main/kotlin/com/nisemoe/nise/controller/FollowsController.kt index 00bd1fb..357a5c1 100644 --- a/nise-backend/src/main/kotlin/com/nisemoe/nise/controller/FollowsController.kt +++ b/nise-backend/src/main/kotlin/com/nisemoe/nise/controller/FollowsController.kt @@ -40,6 +40,7 @@ class FollowsController( @GetMapping("follows") fun getFollowsBanStatus(): ResponseEntity { + authService.getCurrentUser().userId val follows = dslContext.select( USERS.USER_ID, USERS.USERNAME, diff --git a/nise-backend/src/main/kotlin/com/nisemoe/nise/service/AuthService.kt b/nise-backend/src/main/kotlin/com/nisemoe/nise/service/AuthService.kt index 8cacd1c..cb0a838 100644 --- a/nise-backend/src/main/kotlin/com/nisemoe/nise/service/AuthService.kt +++ b/nise-backend/src/main/kotlin/com/nisemoe/nise/service/AuthService.kt @@ -6,6 +6,7 @@ import org.springframework.security.authentication.AnonymousAuthenticationToken import org.springframework.security.core.context.SecurityContextHolder import org.springframework.security.oauth2.core.user.DefaultOAuth2User import org.springframework.stereotype.Service +import java.time.OffsetDateTime @Service class AuthService( @@ -14,7 +15,11 @@ class AuthService( data class UserInfo( val userId: Long, - val username: String + val username: String, + + val country: String?, + val joinDate: OffsetDateTime?, + ) fun isAdmin(): Boolean { @@ -39,7 +44,9 @@ class AuthService( return UserInfo( userId = (userDetails.attributes["id"] as Int).toLong(), - username = userDetails.attributes["username"] as String + username = userDetails.attributes["username"] as String, + country = userDetails.attributes["countryCode"] as String?, + joinDate = OffsetDateTime.parse(userDetails.attributes["joinDate"] as String) ) } diff --git a/nise-circleguard/Dockerfile b/nise-circleguard/Dockerfile index 20ea861..9eed673 100644 --- a/nise-circleguard/Dockerfile +++ b/nise-circleguard/Dockerfile @@ -22,7 +22,7 @@ RUN sed -i '238s|return \[x for x in arr if lower_limit < x < upper_limit\]|arr_ COPY ./src/ ./src/ -ENV GUNICORN_CMD_ARGS="--bind=0.0.0.0:5000 --workers=10" +ENV GUNICORN_CMD_ARGS="--bind=0.0.0.0:5000 --workers=16" # Run gunicorn with the application CMD ["gunicorn", "--chdir", "src", "main:app"] \ No newline at end of file diff --git a/nise-frontend/src/app/app-routing.module.ts b/nise-frontend/src/app/app-routing.module.ts index 9cfd6d7..940bc5b 100644 --- a/nise-frontend/src/app/app-routing.module.ts +++ b/nise-frontend/src/app/app-routing.module.ts @@ -9,7 +9,7 @@ import {ViewReplayPairComponent} from "./view-replay-pair/view-replay-pair.compo import {SearchComponent} from "./search/search.component"; import {ContributeComponent} from "./contribute/contribute.component"; import {BanlistComponent} from "./banlist/banlist.component"; -import {FollowsComponent} from "./follows/follows.component"; +import {ProfileComponent} from "./profile/profile.component"; const routes: Routes = [ {path: 'sus/:f', component: ViewSuspiciousScoresComponent, title: '/sus/'}, @@ -25,7 +25,7 @@ const routes: Routes = [ {path: 'p/:replay1Id/:replay2Id', component: ViewReplayPairComponent}, - {path: 'follows', component: FollowsComponent, title: '/follows/'}, + {path: 'profile', component: ProfileComponent}, {path: 'banlist', component: BanlistComponent, title: '/ban/'}, {path: 'contribute', component: ContributeComponent, title: '/contribute/ <3'}, diff --git a/nise-frontend/src/app/app.component.css b/nise-frontend/src/app/app.component.css index a04bd0a..2d535a8 100644 --- a/nise-frontend/src/app/app.component.css +++ b/nise-frontend/src/app/app.component.css @@ -15,3 +15,10 @@ .link-pink:hover { color: rgba(234, 78, 179, 0.97) } + +.logout-btn { + padding: 1px 2px 2px 1px; + font-size: 14px; + font-weight: bold; + border: 1px dashed rgba(151, 151, 151, 0.97); +} diff --git a/nise-frontend/src/app/app.component.html b/nise-frontend/src/app/app.component.html index f1ec7d7..324ff0f 100644 --- a/nise-frontend/src/app/app.component.html +++ b/nise-frontend/src/app/app.component.html @@ -18,7 +18,7 @@
- hi, {{this.userService.currentUser?.username}} Logout + hi, {{this.userService.currentUser?.username}} Logout Login @@ -26,6 +26,13 @@
+
+ Players: {{ this.statistics?.total_users | number }} | Beatmaps: {{ this.statistics?.total_beatmaps | number }} | Scores: {{ this.statistics?.total_scores | number }} + + | Bans: {{ this.statistics?.total_bans | number }} + +
+
v20240309 diff --git a/nise-frontend/src/app/app.component.ts b/nise-frontend/src/app/app.component.ts index 4655b96..bd56f63 100644 --- a/nise-frontend/src/app/app.component.ts +++ b/nise-frontend/src/app/app.component.ts @@ -1,28 +1,57 @@ -import {Component} from '@angular/core'; +import {Component, OnInit} from '@angular/core'; import {Router, RouterLink, RouterOutlet} from "@angular/router"; import {UserService} from "../corelib/service/user.service"; -import {NgIf} from '@angular/common'; +import {DecimalPipe, NgIf} from '@angular/common'; import {FormsModule} from '@angular/forms'; +import {Observable} from "rxjs"; +import {environment} from "../environments/environment"; +import {LocalCacheService} from "../corelib/service/local-cache.service"; + +interface Statistics { + total_beatmaps: number; + total_users: number; + total_scores: number; + total_replay_scores: number; + total_replay_similarity: number; + total_bans: number; +} + @Component({ selector: 'app-root', standalone: true, - imports: [ - RouterLink, - FormsModule, - NgIf, - RouterOutlet - ], + imports: [ + RouterLink, + FormsModule, + NgIf, + RouterOutlet, + DecimalPipe + ], templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) -export class AppComponent { +export class AppComponent implements OnInit { + statistics: Statistics | null = null; term: string = ''; constructor(private router: Router, + private localCacheService: LocalCacheService, public userService: UserService - ) { + ) { } + + ngOnInit(): void { + this.getStatistics().subscribe((response: Statistics) => { + this.statistics = response; + }); + } + + getStatistics(): Observable { + return this.localCacheService.fetchData( + 'statistics', + `${environment.apiUrl}/stats`, + 60 + ); } onSubmit(): void { diff --git a/nise-frontend/src/app/banlist/banlist.component.html b/nise-frontend/src/app/banlist/banlist.component.html index 33a6b8a..0d2ad0e 100644 --- a/nise-frontend/src/app/banlist/banlist.component.html +++ b/nise-frontend/src/app/banlist/banlist.component.html @@ -21,55 +21,83 @@ null - - - - - - - - - - - - - - - - - - - - - - - -
UsernameTime playedTotal PPRankLast checkApproximate ban date
- - - - {{ user.username }} - - - - {{ formatDuration(user.secondsPlayed) }} - - - - {{ user.pp | number: '1.0-0' }} - - - - #{{ user.rank | number }} - - - - {{ calculateTimeAgo(user.lastUpdate) }} - - - {{ user.approximateBanTime | date: 'medium' }} - -
+ +
+ tools +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
UsernameTime playedTotal PPRankLast checkApproximate ban date
+ + + + {{ user.username }} + + + + {{ formatDuration(user.secondsPlayed) }} + + + + {{ user.pp | number: '1.0-0' }} + + + + #{{ user.rank | number }} + + + + {{ calculateTimeAgo(user.lastUpdate) }} + + + {{ user.approximateBanTime | date: 'medium' }} + +
+
+

Total results: {{ this.banlist.pagination.totalResults | number }}

+

Page: {{ this.banlist.pagination.currentPage | number }} / {{ this.banlist.pagination.totalPages | number }}

+
+ + ... + + ... + +
+ + +
+
diff --git a/nise-frontend/src/app/banlist/banlist.component.ts b/nise-frontend/src/app/banlist/banlist.component.ts index 188a325..fbccbcb 100644 --- a/nise-frontend/src/app/banlist/banlist.component.ts +++ b/nise-frontend/src/app/banlist/banlist.component.ts @@ -6,6 +6,8 @@ import {calculateTimeAgo, formatDuration} from "../format"; import {RouterLink} from "@angular/router"; import {CuteProgressbarComponent} from "../../corelib/components/cute-progressbar/cute-progressbar.component"; import {CuteLoadingComponent} from "../../corelib/components/cute-loading/cute-loading.component"; +import {DownloadFilesService} from "../../corelib/service/download-files.service"; +import {CalculatePageRangePipe} from "../../corelib/calculate-page-range.pipe"; interface BanlistResponse { pagination: BanlistPagination; @@ -41,7 +43,8 @@ interface BanlistEntry { DatePipe, DecimalPipe, CuteProgressbarComponent, - CuteLoadingComponent + CuteLoadingComponent, + CalculatePageRangePipe ], templateUrl: './banlist.component.html', styleUrl: './banlist.component.css' @@ -51,15 +54,18 @@ export class BanlistComponent implements OnInit { isLoading = true; banlist: BanlistResponse | null = null; - constructor(private httpClient: HttpClient) { } + constructor( + private httpClient: HttpClient, + public downloadFilesService: DownloadFilesService + ) { } ngOnInit(): void { this.getBanlist(); } - getBanlist(): void { + getBanlist(page: number = 1): void { const body = { - page: 1 + page: page } this.httpClient.post(`${environment.apiUrl}/banlist`, body).subscribe(response => { this.banlist = response; @@ -69,4 +75,5 @@ export class BanlistComponent implements OnInit { protected readonly calculateTimeAgo = calculateTimeAgo; protected readonly formatDuration = formatDuration; + protected readonly Math = Math; } diff --git a/nise-frontend/src/app/contribute/contribute.component.html b/nise-frontend/src/app/contribute/contribute.component.html index 5a2aab9..06ff51a 100644 --- a/nise-frontend/src/app/contribute/contribute.component.html +++ b/nise-frontend/src/app/contribute/contribute.component.html @@ -1,39 +1,32 @@ -
- -
-
- -
- -

# contributing to the project

-

if you'd like to keep the project healthy and funded in the long term, you are invited to directly contribute.

-

the website does not run ads, paywall features, or collect your private data in any way. i have no intention to change that since I want to provide the best possible service to the osu! community.

-

still, hosting a (relatively) computationally expensive service has costs that are simply unavoidable. that's why I'd encourage people that find this website useful to contribute:

- -

the money will be used to pay for the server hosting and development time.

- - - - - - - - - - -
- - - - - -
server hosting~220$/year
domain~17$/year
total~237$/year
-
+
+
+ +

# contributing to the project

+

if you'd like to keep the project healthy and funded in the long term, you are invited to directly contribute.

+

the website does not run ads, paywall features, or collect your private data in any way. i have no intention to change that since I want to provide the best possible service to the osu! community.

+

still, hosting a (relatively) computationally expensive service has costs that are simply unavoidable. that's why I'd encourage people that find this website useful to contribute:

+ +

the money will be used to pay for the server hosting and development costs.

+ + + + + + + + + + +
+ + + + + +
server hosting~220$/year
domain~17$/year
total~237$/year
-
diff --git a/nise-frontend/src/app/home/home.component.html b/nise-frontend/src/app/home/home.component.html index e8462cb..8895621 100644 --- a/nise-frontend/src/app/home/home.component.html +++ b/nise-frontend/src/app/home/home.component.html @@ -1,11 +1,4 @@ -
- Players: {{ this.statistics?.total_users | number }} | Beatmaps: {{ this.statistics?.total_beatmaps | number }} | Scores: {{ this.statistics?.total_scores | number }} - - | Bans: {{ this.statistics?.total_bans | number }} - -
- -
+
diff --git a/nise-frontend/src/app/home/home.component.ts b/nise-frontend/src/app/home/home.component.ts index 64f46e8..2f25a7c 100644 --- a/nise-frontend/src/app/home/home.component.ts +++ b/nise-frontend/src/app/home/home.component.ts @@ -1,24 +1,14 @@ import {Component, OnDestroy, OnInit} from '@angular/core'; -import {Observable, Subscription} from "rxjs"; +import {Subscription} from "rxjs"; import {environment} from "../../environments/environment"; -import {LocalCacheService} from "../../corelib/service/local-cache.service"; import {RxStompService} from "../../corelib/stomp/stomp.service"; import {Message} from "@stomp/stompjs/esm6"; -import {ErrorDistribution, ReplayData, ReplayDataChart, ReplayDataSimilarScore} from "../replays"; +import {ReplayData} from "../replays"; import {DecimalPipe, NgForOf, NgIf} from "@angular/common"; import {Router, RouterLink} from "@angular/router"; import {HttpClient} from "@angular/common/http"; import {CuteLoadingComponent} from "../../corelib/components/cute-loading/cute-loading.component"; -interface Statistics { - total_beatmaps: number; - total_users: number; - total_scores: number; - total_replay_scores: number; - total_replay_similarity: number; - total_bans: number; -} - interface AnalyzeReplayResponse { id: string; } @@ -41,13 +31,11 @@ export class HomeComponent implements OnInit, OnDestroy { liveScores: ReplayData[] = []; liveScoresSub: Subscription | undefined; - statistics: Statistics | null = null; wantsConnection: boolean = true; loading = false; constructor( - private localCacheService: LocalCacheService, private router: Router, private httpClient: HttpClient, private rxStompService: RxStompService, @@ -63,10 +51,6 @@ export class HomeComponent implements OnInit, OnDestroy { } else { this.subscribe(); } - - this.getStatistics().subscribe((response: Statistics) => { - this.statistics = response; - }); } private subscribe() { @@ -96,14 +80,6 @@ export class HomeComponent implements OnInit, OnDestroy { } } - getStatistics(): Observable { - return this.localCacheService.fetchData( - 'statistics', - `${environment.apiUrl}/stats`, - 60 - ); - } - uploadReplay(event: any) { if (event.target.files.length <= 0) { return; diff --git a/nise-frontend/src/app/follows/follows.component.css b/nise-frontend/src/app/profile/profile.component.css similarity index 100% rename from nise-frontend/src/app/follows/follows.component.css rename to nise-frontend/src/app/profile/profile.component.css diff --git a/nise-frontend/src/app/follows/follows.component.html b/nise-frontend/src/app/profile/profile.component.html similarity index 58% rename from nise-frontend/src/app/follows/follows.component.html rename to nise-frontend/src/app/profile/profile.component.html index 93ac4d0..2ac4354 100644 --- a/nise-frontend/src/app/follows/follows.component.html +++ b/nise-frontend/src/app/profile/profile.component.html @@ -1,7 +1,16 @@
+

hi, {{ this.userService.currentUser?.username }}

+

# follow-list

- + +
+

You are not following anyone!

+

You can follow users by going on their profile and clicking the (+) Add follow buttan.

+

Then, they'll appear here, and you'll be able to check if they've been banned or not.

+
+
+
diff --git a/nise-frontend/src/app/follows/follows.component.ts b/nise-frontend/src/app/profile/profile.component.ts similarity index 66% rename from nise-frontend/src/app/follows/follows.component.ts rename to nise-frontend/src/app/profile/profile.component.ts index cb51047..c262f3b 100644 --- a/nise-frontend/src/app/follows/follows.component.ts +++ b/nise-frontend/src/app/profile/profile.component.ts @@ -4,6 +4,8 @@ import {environment} from "../../environments/environment"; import {JsonPipe, NgForOf, NgIf} from "@angular/common"; import {calculateTimeAgo} from "../format"; import {RouterLink} from "@angular/router"; +import {UserService} from "../../corelib/service/user.service"; +import {Title} from "@angular/platform-browser"; interface FollowsBanStatusResponse { follows: FollowsBanStatusEntry[]; @@ -18,7 +20,7 @@ interface FollowsBanStatusEntry { @Component({ - selector: 'app-follows', + selector: 'app-profile', standalone: true, imports: [ JsonPipe, @@ -26,16 +28,21 @@ interface FollowsBanStatusEntry { NgIf, RouterLink ], - templateUrl: './follows.component.html', - styleUrl: './follows.component.css' + templateUrl: './profile.component.html', + styleUrl: './profile.component.css' }) -export class FollowsComponent implements OnInit { +export class ProfileComponent implements OnInit { follows: FollowsBanStatusResponse | null = null; - constructor(private httpClient: HttpClient) { } + constructor( + private httpClient: HttpClient, + private title: Title, + public userService: UserService + ) { } ngOnInit(): void { + this.title.setTitle(`hi, ${this.userService.currentUser!.username}`); this.getFollows(); }
Username