mirror of
https://github.com/block-core/angor-hub-old.git
synced 2026-01-30 07:04:21 +01:00
Refactor explore and profile component code
This commit is contained in:
@@ -19,15 +19,7 @@ import { NgClass, PercentPipe, I18nPluralPipe, CommonModule } from '@angular/com
|
||||
import { MetadataService } from 'app/services/metadata.service';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
import { IndexedDBService } from 'app/services/indexed-db.service';
|
||||
|
||||
interface Project {
|
||||
projectIdentifier: string;
|
||||
nostrPubKey: string;
|
||||
displayName?: string;
|
||||
about?: string;
|
||||
picture?: string;
|
||||
banner?:string
|
||||
}
|
||||
import { Project } from 'app/interface/project.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'explore',
|
||||
@@ -54,22 +46,26 @@ export class ExploreComponent implements OnInit, OnDestroy {
|
||||
private router: Router,
|
||||
private stateService: StateService,
|
||||
private metadataService: MetadataService,
|
||||
private _indexedDBService: IndexedDBService,
|
||||
private _changeDetectorRef: ChangeDetectorRef
|
||||
private indexedDBService: IndexedDBService,
|
||||
private changeDetectorRef: ChangeDetectorRef
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.projects = this.stateService.getProjects();
|
||||
this.filteredProjects = [...this.projects];
|
||||
|
||||
if (this.projects.length === 0) {
|
||||
this.loadProjects();
|
||||
} else {
|
||||
this.loading = false;
|
||||
|
||||
this.projects.forEach(project => this.subscribeToProjectMetadata(project));
|
||||
this.projects.forEach(project => {
|
||||
if (!project.displayName || !project.about) {
|
||||
this.loadMetadataForProject(project);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this._indexedDBService.getMetadataStream()
|
||||
this.indexedDBService.getMetadataStream()
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((updatedMetadata) => {
|
||||
if (updatedMetadata) {
|
||||
@@ -81,6 +77,7 @@ export class ExploreComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
loadProjects(): void {
|
||||
if (this.loading || this.errorMessage === 'No more projects found') return;
|
||||
|
||||
@@ -103,12 +100,12 @@ export class ExploreComponent implements OnInit, OnDestroy {
|
||||
this.projects.forEach(project => this.subscribeToProjectMetadata(project));
|
||||
}
|
||||
this.loading = false;
|
||||
this._changeDetectorRef.detectChanges();
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}).catch((error: any) => {
|
||||
console.error('Error fetching projects:', error);
|
||||
this.errorMessage = 'Error fetching projects. Please try again later.';
|
||||
this.loading = false;
|
||||
this._changeDetectorRef.detectChanges();
|
||||
this.changeDetectorRef.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -142,7 +139,7 @@ export class ExploreComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
this.filteredProjects = [...this.projects];
|
||||
this._changeDetectorRef.detectChanges();
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
subscribeToProjectMetadata(project: Project): void {
|
||||
|
||||
@@ -17,7 +17,6 @@ import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { Router, RouterLink } from '@angular/router';
|
||||
import { AngorCardComponent } from '@angor/components/card';
|
||||
import { AngorConfigService } from '@angor/services/config';
|
||||
import { SignerService } from 'app/services/signer.service';
|
||||
import { MetadataService } from 'app/services/metadata.service';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
@@ -53,8 +52,6 @@ export class ProfileComponent implements OnInit, OnDestroy {
|
||||
|
||||
constructor(
|
||||
private _changeDetectorRef: ChangeDetectorRef,
|
||||
private _router: Router,
|
||||
private _angorConfigService: AngorConfigService,
|
||||
private _metadataService: MetadataService,
|
||||
private _signerService: SignerService,
|
||||
private _indexedDBService: IndexedDBService
|
||||
|
||||
8
src/app/interface/project.interface.ts
Normal file
8
src/app/interface/project.interface.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export interface Project {
|
||||
projectIdentifier: string;
|
||||
nostrPubKey: string;
|
||||
displayName?: string;
|
||||
about?: string;
|
||||
picture?: string;
|
||||
banner?:string
|
||||
}
|
||||
@@ -46,6 +46,7 @@ export class UserComponent implements OnInit, OnDestroy {
|
||||
theme: string;
|
||||
themes: Themes;
|
||||
|
||||
|
||||
constructor(
|
||||
private _changeDetectorRef: ChangeDetectorRef,
|
||||
private _router: Router,
|
||||
@@ -57,18 +58,6 @@ export class UserComponent implements OnInit, OnDestroy {
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadUserProfile();
|
||||
|
||||
|
||||
this._indexedDBService.getMetadataStream()
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((updatedMetadata) => {
|
||||
if (updatedMetadata && updatedMetadata.pubkey === this.user?.pubkey) {
|
||||
this.metadata = updatedMetadata.metadata;
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this._angorConfigService.config$
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((config: AngorConfig) => {
|
||||
@@ -76,6 +65,23 @@ export class UserComponent implements OnInit, OnDestroy {
|
||||
this.config = config;
|
||||
this._changeDetectorRef.detectChanges();
|
||||
});
|
||||
this.loadUserProfile();
|
||||
|
||||
this._indexedDBService.getMetadataStream()
|
||||
.pipe(takeUntil(this._unsubscribeAll))
|
||||
.subscribe((updatedMetadata) => {
|
||||
if (updatedMetadata && updatedMetadata.pubkey === this.user?.pubkey) {
|
||||
this.metadata = updatedMetadata.metadata;
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
private async loadUserProfile(): Promise<void> {
|
||||
@@ -86,10 +92,11 @@ export class UserComponent implements OnInit, OnDestroy {
|
||||
if (!publicKey) {
|
||||
this.errorMessage = 'No public key found. Please log in again.';
|
||||
this.isLoading = false;
|
||||
this._changeDetectorRef.markForCheck();
|
||||
this._changeDetectorRef.detectChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.user = { pubkey: publicKey };
|
||||
|
||||
try {
|
||||
@@ -112,17 +119,13 @@ export class UserComponent implements OnInit, OnDestroy {
|
||||
} catch (error) {
|
||||
console.error('Failed to load profile data:', error);
|
||||
this.errorMessage = 'Failed to load profile data. Please try again later.';
|
||||
this._changeDetectorRef.detectChanges();
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this._unsubscribeAll.next(null);
|
||||
this._unsubscribeAll.complete();
|
||||
}
|
||||
|
||||
logout(): void {
|
||||
this._router.navigate(['/logout']);
|
||||
}
|
||||
|
||||
@@ -1,23 +1,112 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import localForage from 'localforage';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { Project, ProjectStats } from './projects.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class IndexedDBService {
|
||||
private metadataSubject = new BehaviorSubject<any>(null);
|
||||
private projectsSubject = new BehaviorSubject<Project[]>([]);
|
||||
private projectStatsSubject = new BehaviorSubject<{ [key: string]: ProjectStats }>({});
|
||||
|
||||
private userStore: LocalForage;
|
||||
private projectsStore: LocalForage;
|
||||
private projectStatsStore: LocalForage;
|
||||
|
||||
constructor() {
|
||||
localForage.config({
|
||||
|
||||
this.userStore = localForage.createInstance({
|
||||
driver: localForage.INDEXEDDB,
|
||||
name: 'user-database',
|
||||
name: 'angor-hub',
|
||||
version: 1.0,
|
||||
storeName: 'users',
|
||||
description: 'Store for user metadata',
|
||||
});
|
||||
|
||||
this.projectsStore = localForage.createInstance({
|
||||
driver: localForage.INDEXEDDB,
|
||||
name: 'angor-hub',
|
||||
version: 1.0,
|
||||
storeName: 'projects',
|
||||
description: 'Store for projects',
|
||||
});
|
||||
|
||||
this.projectStatsStore = localForage.createInstance({
|
||||
driver: localForage.INDEXEDDB,
|
||||
name: 'angor-hub',
|
||||
version: 1.0,
|
||||
storeName: 'projectStats',
|
||||
description: 'Store for project statistics',
|
||||
});
|
||||
|
||||
this.loadAllProjectsFromDB();
|
||||
this.loadAllProjectStatsFromDB();
|
||||
}
|
||||
|
||||
// Returns projects as observable
|
||||
getProjectsObservable(): Observable<Project[]> {
|
||||
return this.projectsSubject.asObservable();
|
||||
}
|
||||
|
||||
// Save new project and notify subscribers
|
||||
async saveProject(project: Project): Promise<void> {
|
||||
try {
|
||||
await this.projectsStore.setItem(project.projectIdentifier, project);
|
||||
const updatedProjects = await this.getAllProjects();
|
||||
this.projectsSubject.next(updatedProjects);
|
||||
} catch (error) {
|
||||
console.error(`Error saving project ${project.projectIdentifier} to IndexedDB:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
async getProject(projectIdentifier: string): Promise<Project | null> {
|
||||
try {
|
||||
const project = await this.projectsStore.getItem<Project>(projectIdentifier);
|
||||
return project || null;
|
||||
} catch (error) {
|
||||
console.error(`Error getting project ${projectIdentifier} from IndexedDB:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getAllProjects(): Promise<Project[]> {
|
||||
try {
|
||||
const projects: Project[] = [];
|
||||
await this.projectsStore.iterate<Project, void>((value) => {
|
||||
projects.push(value);
|
||||
});
|
||||
return projects;
|
||||
} catch (error) {
|
||||
console.error('Error getting all projects from IndexedDB:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
getProjectStatsObservable(): Observable<{ [key: string]: ProjectStats }> {
|
||||
return this.projectStatsSubject.asObservable();
|
||||
}
|
||||
|
||||
async saveProjectStats(projectIdentifier: string, stats: ProjectStats): Promise<void> {
|
||||
try {
|
||||
await this.projectStatsStore.setItem(projectIdentifier, stats);
|
||||
const updatedStats = await this.getAllProjectStats();
|
||||
this.projectStatsSubject.next(updatedStats);
|
||||
} catch (error) {
|
||||
console.error(`Error saving project stats for ${projectIdentifier} to IndexedDB:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
async getProjectStats(projectIdentifier: string): Promise<ProjectStats | null> {
|
||||
try {
|
||||
const stats = await this.projectStatsStore.getItem<ProjectStats>(projectIdentifier);
|
||||
return stats || null;
|
||||
} catch (error) {
|
||||
console.error(`Error getting project stats for ${projectIdentifier} from IndexedDB:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
getMetadataStream(): Observable<any> {
|
||||
return this.metadataSubject.asObservable();
|
||||
@@ -25,7 +114,7 @@ export class IndexedDBService {
|
||||
|
||||
async getUserMetadata(pubkey: string): Promise<any | null> {
|
||||
try {
|
||||
const metadata = await localForage.getItem(pubkey);
|
||||
const metadata = await this.userStore.getItem(pubkey);
|
||||
return metadata;
|
||||
} catch (error) {
|
||||
console.error('Error getting metadata from IndexedDB:', error);
|
||||
@@ -35,7 +124,7 @@ export class IndexedDBService {
|
||||
|
||||
async saveUserMetadata(pubkey: string, metadata: any): Promise<void> {
|
||||
try {
|
||||
await localForage.setItem(pubkey, metadata);
|
||||
await this.userStore.setItem(pubkey, metadata);
|
||||
this.metadataSubject.next({ pubkey, metadata });
|
||||
} catch (error) {
|
||||
console.error('Error saving metadata to IndexedDB:', error);
|
||||
@@ -44,36 +133,63 @@ export class IndexedDBService {
|
||||
|
||||
async removeUserMetadata(pubkey: string): Promise<void> {
|
||||
try {
|
||||
await localForage.removeItem(pubkey);
|
||||
await this.userStore.removeItem(pubkey);
|
||||
this.metadataSubject.next({ pubkey, metadata: null });
|
||||
} catch (error) {
|
||||
console.error('Error removing metadata from IndexedDB:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async clearAllMetadata(): Promise<void> {
|
||||
private async loadAllProjectsFromDB(): Promise<void> {
|
||||
try {
|
||||
await localForage.clear();
|
||||
this.metadataSubject.next(null);
|
||||
const projects = await this.getAllProjects();
|
||||
this.projectsSubject.next(projects);
|
||||
} catch (error) {
|
||||
console.error('Error clearing all metadata:', error);
|
||||
console.error('Error loading projects from IndexedDB:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async getAllProjectStats(): Promise<{ [key: string]: ProjectStats }> {
|
||||
try {
|
||||
const statsMap: { [key: string]: ProjectStats } = {};
|
||||
await this.projectStatsStore.iterate<ProjectStats, void>((value, key) => {
|
||||
statsMap[key] = value;
|
||||
});
|
||||
return statsMap;
|
||||
} catch (error) {
|
||||
console.error('Error getting all project stats from IndexedDB:', error);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
private async loadAllProjectStatsFromDB(): Promise<void> {
|
||||
try {
|
||||
const stats = await this.getAllProjectStats();
|
||||
this.projectStatsSubject.next(stats);
|
||||
} catch (error) {
|
||||
console.error('Error loading project stats from IndexedDB:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async getAllUsers(): Promise<any[]> {
|
||||
try {
|
||||
const allKeys = await localForage.keys();
|
||||
const users = [];
|
||||
for (const key of allKeys) {
|
||||
const user = await localForage.getItem(key);
|
||||
if (user) {
|
||||
users.push(user);
|
||||
}
|
||||
}
|
||||
const users: any[] = [];
|
||||
await this.userStore.iterate((value) => {
|
||||
users.push(value);
|
||||
});
|
||||
return users;
|
||||
} catch (error) {
|
||||
console.error('Error getting all users from IndexedDB:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async clearAllMetadata(): Promise<void> {
|
||||
try {
|
||||
await this.userStore.clear();
|
||||
this.metadataSubject.next(null);
|
||||
} catch (error) {
|
||||
console.error('Error clearing all metadata:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpResponse } from '@angular/common/http';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { of, Observable } from 'rxjs';
|
||||
import { IndexerService } from './indexer.service';
|
||||
import { IndexedDBService } from './indexed-db.service';
|
||||
|
||||
export interface Project {
|
||||
founderKey: string;
|
||||
@@ -26,7 +27,7 @@ export interface ProjectStats {
|
||||
})
|
||||
export class ProjectsService {
|
||||
private offset = 0;
|
||||
private limit = 45;
|
||||
private limit = 21;
|
||||
private totalProjects = 0;
|
||||
private loading = false;
|
||||
private projects: Project[] = [];
|
||||
@@ -36,8 +37,8 @@ export class ProjectsService {
|
||||
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private indexerService: IndexerService
|
||||
|
||||
private indexerService: IndexerService,
|
||||
private indexedDBService: IndexedDBService
|
||||
) {
|
||||
this.loadNetwork();
|
||||
}
|
||||
@@ -45,60 +46,74 @@ export class ProjectsService {
|
||||
loadNetwork() {
|
||||
this.selectedNetwork = this.indexerService.getNetwork();
|
||||
}
|
||||
|
||||
async fetchProjects(): Promise<Project[]> {
|
||||
if (this.loading || this.noMoreProjects) {
|
||||
return [];
|
||||
return [];
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
const indexerUrl = this.indexerService.getPrimaryIndexer(this.selectedNetwork);
|
||||
const url = this.totalProjectsFetched
|
||||
? `${indexerUrl}api/query/Angor/projects?offset=${this.offset}&limit=${this.limit}`
|
||||
: `${indexerUrl}api/query/Angor/projects?limit=${this.limit}`;
|
||||
? `${indexerUrl}api/query/Angor/projects?offset=${this.offset}&limit=${this.limit}`
|
||||
: `${indexerUrl}api/query/Angor/projects?limit=${this.limit}`;
|
||||
|
||||
try {
|
||||
const response = await this.http
|
||||
.get<Project[]>(url, { observe: 'response' })
|
||||
.toPromise();
|
||||
const response = await this.http.get<Project[]>(url, { observe: 'response' }).toPromise();
|
||||
|
||||
if (!this.totalProjectsFetched && response && response.headers) {
|
||||
const paginationTotal = response.headers.get('pagination-total');
|
||||
this.totalProjects = paginationTotal ? +paginationTotal : 0;
|
||||
this.totalProjectsFetched = true;
|
||||
if (!this.totalProjectsFetched && response && response.headers) {
|
||||
const paginationTotal = response.headers.get('pagination-total');
|
||||
this.totalProjects = paginationTotal ? +paginationTotal : 0;
|
||||
this.totalProjectsFetched = true;
|
||||
this.offset = Math.max(this.totalProjects - this.limit, 0);
|
||||
}
|
||||
|
||||
this.offset = Math.max(this.totalProjects - this.limit, 0);
|
||||
}
|
||||
const newProjects = response?.body || [];
|
||||
|
||||
const newProjects = response?.body || [];
|
||||
if (!newProjects.length) {
|
||||
this.noMoreProjects = true;
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!newProjects || newProjects.length === 0) {
|
||||
this.noMoreProjects = true;
|
||||
return [];
|
||||
} else {
|
||||
const uniqueNewProjects = newProjects.filter(
|
||||
(newProject) =>
|
||||
!this.projects.some(
|
||||
(existingProject) =>
|
||||
existingProject.projectIdentifier === newProject.projectIdentifier
|
||||
newProject => !this.projects.some(
|
||||
existingProject => existingProject.projectIdentifier === newProject.projectIdentifier
|
||||
)
|
||||
);
|
||||
|
||||
if (uniqueNewProjects.length > 0) {
|
||||
this.projects = [...this.projects, ...uniqueNewProjects];
|
||||
this.offset = Math.max(this.offset - this.limit, 0);
|
||||
return uniqueNewProjects;
|
||||
} else {
|
||||
this.noMoreProjects = true;
|
||||
return [];
|
||||
if (!uniqueNewProjects.length) {
|
||||
this.noMoreProjects = true;
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
const saveProjectsPromises = uniqueNewProjects.map(async project => {
|
||||
await this.indexedDBService.saveProject(project);
|
||||
});
|
||||
|
||||
const projectDetailsPromises = uniqueNewProjects.map(async project => {
|
||||
try {
|
||||
const projectDetails = await this.fetchProjectDetails(project.projectIdentifier).toPromise();
|
||||
project.totalInvestmentsCount = projectDetails.totalInvestmentsCount;
|
||||
return project;
|
||||
} catch (error) {
|
||||
console.error(`Error fetching details for project ${project.projectIdentifier}:`, error);
|
||||
return project;
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all([...saveProjectsPromises, ...projectDetailsPromises]);
|
||||
|
||||
this.projects = [...this.projects, ...uniqueNewProjects];
|
||||
this.offset = Math.max(this.offset - this.limit, 0);
|
||||
|
||||
return uniqueNewProjects;
|
||||
} catch (error) {
|
||||
console.error('Error fetching projects:', error);
|
||||
return [];
|
||||
console.error('Error fetching projects:', error);
|
||||
return [];
|
||||
} finally {
|
||||
this.loading = false;
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fetchProjectStats(projectIdentifier: string): Observable<ProjectStats> {
|
||||
@@ -106,29 +121,57 @@ export class ProjectsService {
|
||||
const url = `${indexerUrl}api/query/Angor/projects/${projectIdentifier}/stats`;
|
||||
return this.http.get<ProjectStats>(url).pipe(
|
||||
catchError((error) => {
|
||||
console.error(
|
||||
`Error fetching stats for project ${projectIdentifier}:`,
|
||||
error
|
||||
);
|
||||
console.error(`Error fetching stats for project ${projectIdentifier}:`, error);
|
||||
return of({} as ProjectStats);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async fetchAndSaveProjectStats(projectIdentifier: string): Promise<ProjectStats | null> {
|
||||
try {
|
||||
const stats = await this.fetchProjectStats(projectIdentifier).toPromise();
|
||||
if (stats) {
|
||||
await this.indexedDBService.saveProjectStats(projectIdentifier, stats);
|
||||
}
|
||||
return stats;
|
||||
} catch (error) {
|
||||
console.error(`Error fetching and saving stats for project ${projectIdentifier}:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
fetchProjectDetails(projectIdentifier: string): Observable<Project> {
|
||||
const indexerUrl = this.indexerService.getPrimaryIndexer(this.selectedNetwork);
|
||||
const url = `${indexerUrl}api/query/Angor/projects/${projectIdentifier}`;
|
||||
return this.http.get<Project>(url).pipe(
|
||||
catchError((error) => {
|
||||
console.error(
|
||||
`Error fetching details for project ${projectIdentifier}:`,
|
||||
error
|
||||
);
|
||||
console.error(`Error fetching details for project ${projectIdentifier}:`, error);
|
||||
return of({} as Project);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async fetchAndSaveProjectDetails(projectIdentifier: string): Promise<Project | null> {
|
||||
try {
|
||||
const project = await this.fetchProjectDetails(projectIdentifier).toPromise();
|
||||
if (project) {
|
||||
await this.indexedDBService.saveProject(project);
|
||||
}
|
||||
return project;
|
||||
} catch (error) {
|
||||
console.error(`Error fetching and saving details for project ${projectIdentifier}:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getAllProjectsFromDB(): Promise<Project[]> {
|
||||
return this.indexedDBService.getAllProjects();
|
||||
}
|
||||
|
||||
async getProjectStatsFromDB(projectIdentifier: string): Promise<ProjectStats | null> {
|
||||
return this.indexedDBService.getProjectStats(projectIdentifier);
|
||||
}
|
||||
|
||||
getProjects(): Project[] {
|
||||
return this.projects;
|
||||
}
|
||||
|
||||
@@ -1,46 +1,32 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Project } from 'app/interface/project.interface';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class StateService {
|
||||
private projects: any[] = [];
|
||||
private projectsSubject = new BehaviorSubject<any[]>([]); // Stream for projects updates
|
||||
private projects: Project[] = [];
|
||||
private projectsSubject = new BehaviorSubject<Project[]>([]);
|
||||
|
||||
/**
|
||||
* Returns an observable for project updates.
|
||||
*/
|
||||
getProjectsObservable() {
|
||||
return this.projectsSubject.asObservable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the projects and emits the updated list.
|
||||
*/
|
||||
setProjects(projects: any[]): void {
|
||||
setProjects(projects: Project[]): void {
|
||||
this.projects = projects;
|
||||
this.projectsSubject.next(this.projects); // Emit updated projects
|
||||
this.projectsSubject.next(this.projects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current list of projects.
|
||||
*/
|
||||
getProjects(): any[] {
|
||||
getProjects(): Project[] {
|
||||
return this.projects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean indicating whether there are projects.
|
||||
*/
|
||||
hasProjects(): boolean {
|
||||
return this.projects.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates or adds a project based on its nostrPubKey.
|
||||
*/
|
||||
updateProject(project: any): void {
|
||||
updateProject(project: Project): void {
|
||||
const index = this.projects.findIndex(p => p.nostrPubKey === project.nostrPubKey);
|
||||
|
||||
if (index > -1) {
|
||||
@@ -49,13 +35,10 @@ export class StateService {
|
||||
this.projects.push(project);
|
||||
}
|
||||
|
||||
this.projectsSubject.next(this.projects); // Emit updated projects
|
||||
this.projectsSubject.next(this.projects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific project by its nostrPubKey.
|
||||
*/
|
||||
getProjectByPubKey(nostrPubKey: string): any | undefined {
|
||||
getProjectByPubKey(nostrPubKey: string): Project | undefined {
|
||||
return this.projects.find(p => p.nostrPubKey === nostrPubKey);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user