mirror of
https://github.com/block-core/angor-hub-old.git
synced 2026-01-31 07:34:21 +01:00
Add widgets
This commit is contained in:
@@ -16,23 +16,12 @@ import { MatInputModule } from '@angular/material/input';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { NostrEvent } from 'nostr-tools';
|
||||
import { AngorCardComponent } from '@angor/components/card';
|
||||
import { AngorConfigService } from '@angor/services/config';
|
||||
import { AngorConfirmationService } from '@angor/services/confirmation';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
||||
import { ParseContentService } from 'app/services/parse-content.service';
|
||||
import { SignerService } from 'app/services/signer.service';
|
||||
import { SocialService } from 'app/services/social.service';
|
||||
import { StorageService } from 'app/services/storage.service';
|
||||
import { SubscriptionService } from 'app/services/subscription.service';
|
||||
import { AgoPipe } from 'app/shared/pipes/ago.pipe';
|
||||
import { PostProfileComponent } from '../post-event/post-profile/post-profile.component';
|
||||
import { PostComponent } from 'app/layout/common/post/post.component';
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -72,96 +72,29 @@
|
||||
</div>
|
||||
|
||||
<!-- Separator -->
|
||||
<div class="mx-8 hidden h-8 flex-shrink-0 border-l-2 lg:flex"></div>
|
||||
<div class="flex flex-shrink-0 items-center space-x-6 lg:mt-0">
|
||||
<div
|
||||
*ngIf="isCurrentUserProfile; else otherUserStats"
|
||||
class="mt-6 flex flex-shrink-0 items-center space-x-6 lg:mt-0"
|
||||
>
|
||||
<ng-container *ngIf="stats$ | async as stats">
|
||||
<div class="flex flex-col items-center">
|
||||
<span
|
||||
[matTooltip]="
|
||||
'Total contact: ' + stats.totalContacts
|
||||
"
|
||||
class="font-bold"
|
||||
>
|
||||
{{ stats.followersCount }}
|
||||
</span>
|
||||
<span class="text-secondary text-sm font-medium"
|
||||
>FOLLOWERS</span
|
||||
>
|
||||
</div>
|
||||
<div class="flex flex-shrink-0 items-center space-x-6 lg:mt-0">
|
||||
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="font-bold">{{
|
||||
stats.followingCount
|
||||
}}</span>
|
||||
<span
|
||||
[matTooltip]="
|
||||
'Total contact: ' + stats.totalContacts
|
||||
"
|
||||
class="text-secondary text-sm font-medium"
|
||||
>
|
||||
FOLLOWING
|
||||
</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<ng-template #otherUserStats>
|
||||
<div
|
||||
class="mt-6 flex flex-shrink-0 items-center space-x-6 lg:mt-0"
|
||||
>
|
||||
<div class="flex flex-col items-center">
|
||||
<span
|
||||
[matTooltip]="'Total contact: ' + totalContacts"
|
||||
class="font-bold"
|
||||
>
|
||||
{{ followersCount }}
|
||||
</span>
|
||||
<span class="text-secondary text-sm font-medium"
|
||||
>FOLLOWERS</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-center">
|
||||
<span class="font-bold">{{ followingCount }}</span>
|
||||
<span
|
||||
[matTooltip]="'Total contact: ' + totalContacts"
|
||||
class="text-secondary text-sm font-medium"
|
||||
>
|
||||
FOLLOWING
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<!-- Separator -->
|
||||
<div
|
||||
class="mx-8 hidden h-8 flex-shrink-0 border-l-2 lg:flex"
|
||||
></div>
|
||||
|
||||
<!-- Tools -->
|
||||
<div
|
||||
class="mb-4 mt-8 flex flex-shrink-0 items-center space-x-6 lg:m-0 lg:ml-auto"
|
||||
>
|
||||
<div *ngIf="!isCurrentUserProfile">
|
||||
<button
|
||||
mat-icon-button
|
||||
(click)="toggleFollow()"
|
||||
[matTooltip]="isFollowing ? 'Unfollow' : 'Follow'"
|
||||
>
|
||||
<mat-icon
|
||||
[svgIcon]="
|
||||
isFollowing
|
||||
? 'heroicons_outline:user-minus'
|
||||
: 'heroicons_outline:user-plus'
|
||||
"
|
||||
>
|
||||
|
||||
<div
|
||||
class="flex h-10 w-10 items-center justify-center rounded-full border bg-white shadow-md">
|
||||
<button mat-icon-button >
|
||||
<mat-icon class="icon-size-5" [svgIcon]="'heroicons_outline:chat-bubble-left-right'"></mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="flex h-10 w-10 items-center justify-center rounded-full border bg-white shadow-md">
|
||||
<button mat-icon-button >
|
||||
<mat-icon class="icon-size-5"
|
||||
[svgIcon]="'heroicons_solid:bookmark'">
|
||||
</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
mat-icon-button
|
||||
@@ -508,7 +441,7 @@
|
||||
eventInput.nativeElement.value
|
||||
);
|
||||
trackBy: trackByFn
|
||||
|
||||
|
||||
"
|
||||
class="inline-block whitespace-pre-wrap break-words"
|
||||
>
|
||||
|
||||
@@ -30,7 +30,6 @@ import { ActivatedRoute, Router, RouterLink } from '@angular/router';
|
||||
import { PickerComponent } from '@ctrl/ngx-emoji-mart';
|
||||
import { EventService } from 'app/services/event.service';
|
||||
import { SignerService } from 'app/services/signer.service';
|
||||
import { SocialService } from 'app/services/social.service';
|
||||
import { ContactEvent, StorageService } from 'app/services/storage.service';
|
||||
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
||||
import { Filter, NostrEvent } from 'nostr-tools';
|
||||
@@ -141,7 +140,6 @@ export class ProfileComponent implements OnInit, OnDestroy {
|
||||
private _sanitizer: DomSanitizer,
|
||||
private _route: ActivatedRoute,
|
||||
private _router: Router,
|
||||
private _socialService: SocialService,
|
||||
private _snackBar: MatSnackBar,
|
||||
private _dialog: MatDialog,
|
||||
private _angorConfigService: AngorConfigService,
|
||||
@@ -170,6 +168,17 @@ export class ProfileComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private checkIfRoutePubKeyIsFollowing(): void {
|
||||
if (!this.routePubKey || !this.followersList) {
|
||||
this.isFollowing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.isFollowing = this.followersList.some(follower => follower.pubkey === this.routePubKey);
|
||||
}
|
||||
|
||||
|
||||
private processRouteParams(): void {
|
||||
this._route.paramMap.subscribe((params) => {
|
||||
const routeKey = params.get('pubkey') || '';
|
||||
@@ -198,8 +207,7 @@ export class ProfileComponent implements OnInit, OnDestroy {
|
||||
|
||||
private loadUserProfileData(pubKey: string): void {
|
||||
this.loadUserProfile(pubKey);
|
||||
this.stats$ = this._storageService.getContactStats$(pubKey);
|
||||
}
|
||||
}
|
||||
|
||||
private isValidHexPubkey(pubkey: string): boolean {
|
||||
const hexPattern = /^[a-fA-F0-9]{64}$/;
|
||||
@@ -242,7 +250,7 @@ export class ProfileComponent implements OnInit, OnDestroy {
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
this._changeDetectorRef.detectChanges();
|
||||
this.refreshUI();
|
||||
}
|
||||
|
||||
|
||||
@@ -268,7 +276,7 @@ export class ProfileComponent implements OnInit, OnDestroy {
|
||||
if (newPost.pubkey === this.routePubKey) {
|
||||
this.posts.unshift(newPost);
|
||||
this.posts.sort((a, b) => b.created_at - a.created_at);
|
||||
this._changeDetectorRef.detectChanges();
|
||||
this.refreshUI();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -312,12 +320,12 @@ export class ProfileComponent implements OnInit, OnDestroy {
|
||||
this.errorMessage = null;
|
||||
this.profileUser = null;
|
||||
|
||||
this._changeDetectorRef.detectChanges();
|
||||
this.refreshUI();
|
||||
|
||||
if (!publicKey) {
|
||||
this.errorMessage = 'No public key found. Please log in again.';
|
||||
this.isLoading = false;
|
||||
this._changeDetectorRef.detectChanges();
|
||||
this.refreshUI();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -325,7 +333,7 @@ export class ProfileComponent implements OnInit, OnDestroy {
|
||||
const cachedMetadata = await this._storageService.getProfile(publicKey);
|
||||
if (cachedMetadata) {
|
||||
this.profileUser = cachedMetadata;
|
||||
this._changeDetectorRef.detectChanges();
|
||||
this.refreshUI();
|
||||
}
|
||||
|
||||
this.subscribeToUserProfileAndContacts(publicKey);
|
||||
@@ -386,52 +394,27 @@ export class ProfileComponent implements OnInit, OnDestroy {
|
||||
};
|
||||
|
||||
if (isFollower) {
|
||||
// Add to followers list
|
||||
this.followersList.push(contactEvent);
|
||||
this.followersCount++;
|
||||
this.totalContacts++;
|
||||
this._changeDetectorRef.detectChanges();
|
||||
|
||||
} else {
|
||||
// Add to following list
|
||||
this.followingList.push(contactEvent);
|
||||
this.followingCount++;
|
||||
this.totalContacts++;
|
||||
this._changeDetectorRef.detectChanges();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
this.checkIfRoutePubKeyIsFollowing();
|
||||
this.refreshUI();
|
||||
}
|
||||
|
||||
|
||||
getSafeUrl(url: string): SafeUrl {
|
||||
return this._sanitizer.bypassSecurityTrustUrl(url);
|
||||
}
|
||||
|
||||
async toggleFollow(): Promise<void> {
|
||||
try {
|
||||
const userPubKey = this._signerService.getPublicKey();
|
||||
const routePubKey = this.routePubKey || this.currentUserPubKey;
|
||||
|
||||
if (!routePubKey || !userPubKey) {
|
||||
console.error('Public key missing. Unable to toggle follow.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isFollowing) {
|
||||
await this._socialService.unfollow(routePubKey);
|
||||
|
||||
} else {
|
||||
await this._socialService.follow(routePubKey);
|
||||
}
|
||||
|
||||
this.isFollowing = !this.isFollowing;
|
||||
|
||||
this._changeDetectorRef.detectChanges();
|
||||
} catch (error) {
|
||||
console.error('Failed to toggle follow:', error);
|
||||
}
|
||||
private refreshUI(): void {
|
||||
this._changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
openSnackBar(message: string, action: string = 'dismiss'): void {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<p>call-to-action works!</p>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CallToActionComponent } from './call-to-action.component';
|
||||
|
||||
describe('CallToActionComponent', () => {
|
||||
let component: CallToActionComponent;
|
||||
let fixture: ComponentFixture<CallToActionComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [CallToActionComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(CallToActionComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-call-to-action',
|
||||
imports: [],
|
||||
templateUrl: './call-to-action.component.html',
|
||||
styleUrl: './call-to-action.component.scss'
|
||||
})
|
||||
export class CallToActionComponent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<p>downloadbox works!</p>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DownloadboxComponent } from './downloadbox.component';
|
||||
|
||||
describe('DownloadboxComponent', () => {
|
||||
let component: DownloadboxComponent;
|
||||
let fixture: ComponentFixture<DownloadboxComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [DownloadboxComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(DownloadboxComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-downloadbox',
|
||||
imports: [],
|
||||
templateUrl: './downloadbox.component.html',
|
||||
styleUrl: './downloadbox.component.scss'
|
||||
})
|
||||
export class DownloadboxComponent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<p>image-gallery works!</p>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ImageGalleryComponent } from './image-gallery.component';
|
||||
|
||||
describe('ImageGalleryComponent', () => {
|
||||
let component: ImageGalleryComponent;
|
||||
let fixture: ComponentFixture<ImageGalleryComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ImageGalleryComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ImageGalleryComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-image-gallery',
|
||||
imports: [],
|
||||
templateUrl: './image-gallery.component.html',
|
||||
styleUrl: './image-gallery.component.scss'
|
||||
})
|
||||
export class ImageGalleryComponent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<p>investors-box works!</p>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { InvestorsBoxComponent } from './investors-box.component';
|
||||
|
||||
describe('InvestorsBoxComponent', () => {
|
||||
let component: InvestorsBoxComponent;
|
||||
let fixture: ComponentFixture<InvestorsBoxComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [InvestorsBoxComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(InvestorsBoxComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-investors-box',
|
||||
imports: [],
|
||||
templateUrl: './investors-box.component.html',
|
||||
styleUrl: './investors-box.component.scss'
|
||||
})
|
||||
export class InvestorsBoxComponent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<p>slide-show works!</p>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SlideShowComponent } from './slide-show.component';
|
||||
|
||||
describe('SlideShowComponent', () => {
|
||||
let component: SlideShowComponent;
|
||||
let fixture: ComponentFixture<SlideShowComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [SlideShowComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SlideShowComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-slide-show',
|
||||
imports: [],
|
||||
templateUrl: './slide-show.component.html',
|
||||
styleUrl: './slide-show.component.scss'
|
||||
})
|
||||
export class SlideShowComponent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<p>social-media-links works!</p>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SocialMediaLinksComponent } from './social-media-links.component';
|
||||
|
||||
describe('SocialMediaLinksComponent', () => {
|
||||
let component: SocialMediaLinksComponent;
|
||||
let fixture: ComponentFixture<SocialMediaLinksComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [SocialMediaLinksComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SocialMediaLinksComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-social-media-links',
|
||||
imports: [],
|
||||
templateUrl: './social-media-links.component.html',
|
||||
styleUrl: './social-media-links.component.scss'
|
||||
})
|
||||
export class SocialMediaLinksComponent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<p>team-members works!</p>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TeamMembersComponent } from './team-members.component';
|
||||
|
||||
describe('TeamMembersComponent', () => {
|
||||
let component: TeamMembersComponent;
|
||||
let fixture: ComponentFixture<TeamMembersComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [TeamMembersComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(TeamMembersComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-team-members',
|
||||
imports: [],
|
||||
templateUrl: './team-members.component.html',
|
||||
styleUrl: './team-members.component.scss'
|
||||
})
|
||||
export class TeamMembersComponent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<p>useful-links works!</p>
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UsefulLinksComponent } from './useful-links.component';
|
||||
|
||||
describe('UsefulLinksComponent', () => {
|
||||
let component: UsefulLinksComponent;
|
||||
let fixture: ComponentFixture<UsefulLinksComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [UsefulLinksComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(UsefulLinksComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-useful-links',
|
||||
imports: [],
|
||||
templateUrl: './useful-links.component.html',
|
||||
styleUrl: './useful-links.component.scss'
|
||||
})
|
||||
export class UsefulLinksComponent {
|
||||
|
||||
}
|
||||
1
src/app/components/widgets/zap/zap.component.html
Normal file
1
src/app/components/widgets/zap/zap.component.html
Normal file
@@ -0,0 +1 @@
|
||||
<p>zap works!</p>
|
||||
0
src/app/components/widgets/zap/zap.component.scss
Normal file
0
src/app/components/widgets/zap/zap.component.scss
Normal file
23
src/app/components/widgets/zap/zap.component.spec.ts
Normal file
23
src/app/components/widgets/zap/zap.component.spec.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ZapComponent } from './zap.component';
|
||||
|
||||
describe('ZapComponent', () => {
|
||||
let component: ZapComponent;
|
||||
let fixture: ComponentFixture<ZapComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ZapComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ZapComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
11
src/app/components/widgets/zap/zap.component.ts
Normal file
11
src/app/components/widgets/zap/zap.component.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-zap',
|
||||
imports: [],
|
||||
templateUrl: './zap.component.html',
|
||||
styleUrl: './zap.component.scss'
|
||||
})
|
||||
export class ZapComponent {
|
||||
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Event, Filter, NostrEvent, UnsignedEvent } from 'nostr-tools';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { RelayService } from './relay.service';
|
||||
import { SignerService } from './signer.service';
|
||||
import { QueueService } from './queue-service.service';
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class SocialService {
|
||||
private followersSubject = new Subject<NostrEvent>();
|
||||
private followingSubject = new Subject<NostrEvent>();
|
||||
|
||||
constructor(
|
||||
private relayService: RelayService,
|
||||
private signerService: SignerService,
|
||||
private queueService: QueueService
|
||||
|
||||
) {}
|
||||
|
||||
getFollowersObservable(): Observable<NostrEvent> {
|
||||
return this.followersSubject.asObservable();
|
||||
}
|
||||
|
||||
getFollowingObservable(): Observable<NostrEvent> {
|
||||
return this.followingSubject.asObservable();
|
||||
}
|
||||
|
||||
// Fetch followers
|
||||
async getFollowers(pubkey: string): Promise<any[]> {
|
||||
const filters: Filter[] = [{ kinds: [3], '#p': [pubkey] }];
|
||||
const followers: any[] = [];
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const eventObservable = this.queueService.addRequestToQueue(filters);
|
||||
eventObservable.subscribe({
|
||||
next: (event: NostrEvent) => {
|
||||
followers.push(event);
|
||||
this.followersSubject.next(event);
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('Error fetching followers:', err);
|
||||
reject(err);
|
||||
},
|
||||
complete: () => {
|
||||
resolve(followers);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch who the user is following
|
||||
async getFollowing(pubkey: string): Promise<any[]> {
|
||||
const filters: Filter[] = [{ kinds: [3], authors: [pubkey] }];
|
||||
const following: any[] = [];
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const eventObservable = this.queueService.addRequestToQueue(filters);
|
||||
eventObservable.subscribe({
|
||||
next: (event: NostrEvent) => {
|
||||
const tags = event.tags.filter((tag) => tag[0] === 'p');
|
||||
tags.forEach((tag) => {
|
||||
following.push(tag[1]);
|
||||
this.followingSubject.next(event);
|
||||
});
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('Error fetching following:', err);
|
||||
reject(err);
|
||||
},
|
||||
complete: () => {
|
||||
resolve(following);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Follow a user
|
||||
async follow(pubkeyToFollow: string): Promise<void> {
|
||||
const currentFollowing = this.getFollowingList();
|
||||
if (currentFollowing.includes(pubkeyToFollow)) {
|
||||
console.log(`Already following ${pubkeyToFollow}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the user to the following list
|
||||
const newFollowingList = [...currentFollowing, pubkeyToFollow];
|
||||
this.setFollowingList(newFollowingList);
|
||||
|
||||
const unsignedEvent: UnsignedEvent = this.signerService.getUnsignedEvent(
|
||||
3,
|
||||
newFollowingList.map((f) => ['p', f]),
|
||||
''
|
||||
);
|
||||
|
||||
// Sign and publish the follow event
|
||||
await this.publishSignedEvent(unsignedEvent);
|
||||
console.log(`Now following ${pubkeyToFollow}`);
|
||||
}
|
||||
|
||||
// Unfollow a user
|
||||
async unfollow(pubkeyToUnfollow: string): Promise<void> {
|
||||
const currentFollowing = this.getFollowingList();
|
||||
if (!currentFollowing.includes(pubkeyToUnfollow)) {
|
||||
console.log(`Not following ${pubkeyToUnfollow}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the user from the following list
|
||||
const updatedFollowingList = currentFollowing.filter(
|
||||
(pubkey) => pubkey !== pubkeyToUnfollow
|
||||
);
|
||||
this.setFollowingList(updatedFollowingList);
|
||||
|
||||
const unsignedEvent: UnsignedEvent = this.signerService.getUnsignedEvent(
|
||||
3,
|
||||
updatedFollowingList.map((f) => ['p', f]),
|
||||
''
|
||||
);
|
||||
|
||||
// Sign and publish the unfollow event
|
||||
await this.publishSignedEvent(unsignedEvent);
|
||||
console.log(`Unfollowed ${pubkeyToUnfollow}`);
|
||||
}
|
||||
|
||||
private async publishSignedEvent(unsignedEvent: UnsignedEvent): Promise<void> {
|
||||
const isUsingExtension = await this.signerService.isUsingExtension();
|
||||
let signedEvent: Event;
|
||||
|
||||
if (isUsingExtension) {
|
||||
signedEvent = await this.signerService.signEventWithExtension(unsignedEvent);
|
||||
} else {
|
||||
const secretKey = await this.signerService.getDecryptedSecretKey();
|
||||
if (!secretKey) {
|
||||
throw new Error('Secret key is missing. Unable to sign event.');
|
||||
}
|
||||
signedEvent = this.signerService.getSignedEvent(unsignedEvent, secretKey);
|
||||
}
|
||||
|
||||
this.relayService.publishEventToWriteRelays(signedEvent);
|
||||
}
|
||||
|
||||
// Retrieve following list as tags for publishing follow/unfollow events
|
||||
getFollowingListAsTags(): string[][] {
|
||||
const following = this.getFollowingList();
|
||||
const tags: string[][] = [];
|
||||
|
||||
const relays = this.relayService.getConnectedRelays();
|
||||
|
||||
following.forEach((f) => {
|
||||
relays.forEach((relay) => {
|
||||
tags.push(['p', f, relay, localStorage.getItem(`${f}`) || '']);
|
||||
});
|
||||
});
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
setFollowingListFromTags(tags: string[][]): void {
|
||||
const following: string[] = [];
|
||||
tags.forEach((t) => {
|
||||
following.push(t[1]);
|
||||
});
|
||||
this.setFollowingList(following);
|
||||
}
|
||||
|
||||
setFollowingList(following: string[]): void {
|
||||
const followingSet = Array.from(new Set(following));
|
||||
const newFollowingList = followingSet.filter((s) => s).join(',');
|
||||
localStorage.setItem('following', newFollowingList);
|
||||
}
|
||||
|
||||
getFollowingList(): string[] {
|
||||
const followingRaw = localStorage.getItem('following');
|
||||
if (followingRaw === null || followingRaw === '') {
|
||||
return [];
|
||||
}
|
||||
const following = followingRaw.split(',');
|
||||
return following.filter((value) => /[a-f0-9]{64}/.test(value));
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ export class StateService {
|
||||
}
|
||||
|
||||
await this.subscribeToUserProfile(pubkey);
|
||||
await this.subscribeToUserContacts(pubkey);
|
||||
// await this.subscribeToUserContacts(pubkey);
|
||||
await this.subscribeToUserChats(pubkey);
|
||||
await this.subscribeToUserPosts(pubkey);
|
||||
await this.subscribeToMyLikes(pubkey);
|
||||
@@ -47,40 +47,40 @@ export class StateService {
|
||||
});
|
||||
}
|
||||
|
||||
private async subscribeToUserContacts(pubkey: string): Promise<void> {
|
||||
// private async subscribeToUserContacts(pubkey: string): Promise<void> {
|
||||
|
||||
const contactsLastUpdate = await this.storageService.getLastUpdateDate('contacts');
|
||||
// const contactsLastUpdate = await this.storageService.getLastUpdateDate('contacts');
|
||||
|
||||
const contactsFilter: Filter[] = [
|
||||
{
|
||||
kinds: [Contacts],
|
||||
authors: [pubkey],
|
||||
},
|
||||
{
|
||||
kinds: [Contacts],
|
||||
'#p': [pubkey],
|
||||
},
|
||||
];
|
||||
// const contactsFilter: Filter[] = [
|
||||
// {
|
||||
// kinds: [Contacts],
|
||||
// authors: [pubkey],
|
||||
// },
|
||||
// {
|
||||
// kinds: [Contacts],
|
||||
// '#p': [pubkey],
|
||||
// },
|
||||
// ];
|
||||
|
||||
if (contactsLastUpdate) {
|
||||
const lastUpdateTimestamp = parseInt(contactsLastUpdate, 10);
|
||||
contactsFilter.forEach(filter => filter.since = lastUpdateTimestamp);
|
||||
}
|
||||
// if (contactsLastUpdate) {
|
||||
// const lastUpdateTimestamp = parseInt(contactsLastUpdate, 10);
|
||||
// contactsFilter.forEach(filter => filter.since = lastUpdateTimestamp);
|
||||
// }
|
||||
|
||||
this.subscriptionService.addSubscriptions(contactsFilter, (event: NostrEvent) => {
|
||||
const isFollower = event.pubkey === pubkey;
|
||||
// this.subscriptionService.addSubscriptions(contactsFilter, (event: NostrEvent) => {
|
||||
// const isFollower = event.pubkey === pubkey;
|
||||
|
||||
const contactEvent: ContactEvent = {
|
||||
id: event.id,
|
||||
pubkey: event.pubkey,
|
||||
created_at: event.created_at,
|
||||
tags: event.tags,
|
||||
isFollower,
|
||||
};
|
||||
// const contactEvent: ContactEvent = {
|
||||
// id: event.id,
|
||||
// pubkey: event.pubkey,
|
||||
// created_at: event.created_at,
|
||||
// tags: event.tags,
|
||||
// isFollower,
|
||||
// };
|
||||
|
||||
this.storageService.saveContacts(pubkey, [contactEvent]);
|
||||
});
|
||||
}
|
||||
// this.storageService.saveContacts(pubkey, [contactEvent]);
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
private async subscribeToUserChats(pubkey: string): Promise<void> {
|
||||
|
||||
@@ -61,12 +61,12 @@ export class StorageService {
|
||||
|
||||
this.loadAllProjectsFromDB();
|
||||
this.loadAllProjectStatsFromDB();
|
||||
this.loadAllContactsFromDB();
|
||||
//this.loadAllContactsFromDB();
|
||||
this.loadAllChatEventsFromDB();
|
||||
this.loadAllMyLikesFromDB();
|
||||
this.loadAllNotificationsFromDB();
|
||||
this.loadContactStatsFromDB();
|
||||
this.calculateAndStoreAllContactStats();
|
||||
//this.calculateAndStoreAllContactStats();
|
||||
}
|
||||
|
||||
private createStore(storeName: string): LocalForage {
|
||||
@@ -121,181 +121,181 @@ export class StorageService {
|
||||
|
||||
// --------------------- Contacts Methods ---------------------
|
||||
|
||||
async saveContacts(pubKey: string, contacts: ContactEvent[]): Promise<void> {
|
||||
try {
|
||||
const savedContacts: ContactEvent[] = [];
|
||||
for (const contact of contacts) {
|
||||
const key = `${pubKey}:${contact.id}`;
|
||||
await this.contactsStore.setItem(key, contact);
|
||||
savedContacts.push(contact);
|
||||
}
|
||||
this.contactsSubject.next({ pubKey, contacts: savedContacts });
|
||||
// async saveContacts(pubKey: string, contacts: ContactEvent[]): Promise<void> {
|
||||
// try {
|
||||
// const savedContacts: ContactEvent[] = [];
|
||||
// for (const contact of contacts) {
|
||||
// const key = `${pubKey}:${contact.id}`;
|
||||
// await this.contactsStore.setItem(key, contact);
|
||||
// savedContacts.push(contact);
|
||||
// }
|
||||
// this.contactsSubject.next({ pubKey, contacts: savedContacts });
|
||||
|
||||
await this.calculateAndStoreAllContactStats();
|
||||
// await this.calculateAndStoreAllContactStats();
|
||||
|
||||
await this.setUpdateHistory('contacts');
|
||||
} catch (error) {
|
||||
console.error('Error saving contacts:', error);
|
||||
}
|
||||
}
|
||||
// await this.setUpdateHistory('contacts');
|
||||
// } catch (error) {
|
||||
// console.error('Error saving contacts:', error);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
private contactStatsMap: { [pubKey: string]: BehaviorSubject<{ pubKey: string, totalContacts: number, followersCount: number, followingCount: number }> } = {};
|
||||
// private contactStatsMap: { [pubKey: string]: BehaviorSubject<{ pubKey: string, totalContacts: number, followersCount: number, followingCount: number }> } = {};
|
||||
|
||||
private async calculateAndStoreAllContactStats(): Promise<void> {
|
||||
try {
|
||||
const statsMap: { [pubKey: string]: { totalContacts: number, followersCount: number, followingCount: number } } = {};
|
||||
// private async calculateAndStoreAllContactStats(): Promise<void> {
|
||||
// try {
|
||||
// const statsMap: { [pubKey: string]: { totalContacts: number, followersCount: number, followingCount: number } } = {};
|
||||
|
||||
await this.contactsStore.iterate<ContactEvent, void>((contact, key) => {
|
||||
const [storedPubKey] = key.split(':');
|
||||
if (!statsMap[storedPubKey]) {
|
||||
statsMap[storedPubKey] = { totalContacts: 0, followersCount: 0, followingCount: 0 };
|
||||
}
|
||||
statsMap[storedPubKey].totalContacts++;
|
||||
if (contact.isFollower) {
|
||||
statsMap[storedPubKey].followersCount++;
|
||||
} else {
|
||||
statsMap[storedPubKey].followingCount++;
|
||||
}
|
||||
});
|
||||
// await this.contactsStore.iterate<ContactEvent, void>((contact, key) => {
|
||||
// const [storedPubKey] = key.split(':');
|
||||
// if (!statsMap[storedPubKey]) {
|
||||
// statsMap[storedPubKey] = { totalContacts: 0, followersCount: 0, followingCount: 0 };
|
||||
// }
|
||||
// statsMap[storedPubKey].totalContacts++;
|
||||
// if (contact.isFollower) {
|
||||
// statsMap[storedPubKey].followersCount++;
|
||||
// } else {
|
||||
// statsMap[storedPubKey].followingCount++;
|
||||
// }
|
||||
// });
|
||||
|
||||
for (const pubKey in statsMap) {
|
||||
if (!this.contactStatsMap[pubKey]) {
|
||||
this.contactStatsMap[pubKey] = new BehaviorSubject<{ pubKey: string, totalContacts: number, followersCount: number, followingCount: number }>({
|
||||
pubKey,
|
||||
totalContacts: 0,
|
||||
followersCount: 0,
|
||||
followingCount: 0,
|
||||
});
|
||||
}
|
||||
this.contactStatsMap[pubKey].next({
|
||||
pubKey,
|
||||
totalContacts: statsMap[pubKey].totalContacts,
|
||||
followersCount: statsMap[pubKey].followersCount,
|
||||
followingCount: statsMap[pubKey].followingCount,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error calculating and storing contact stats:', error);
|
||||
}
|
||||
}
|
||||
// for (const pubKey in statsMap) {
|
||||
// if (!this.contactStatsMap[pubKey]) {
|
||||
// this.contactStatsMap[pubKey] = new BehaviorSubject<{ pubKey: string, totalContacts: number, followersCount: number, followingCount: number }>({
|
||||
// pubKey,
|
||||
// totalContacts: 0,
|
||||
// followersCount: 0,
|
||||
// followingCount: 0,
|
||||
// });
|
||||
// }
|
||||
// this.contactStatsMap[pubKey].next({
|
||||
// pubKey,
|
||||
// totalContacts: statsMap[pubKey].totalContacts,
|
||||
// followersCount: statsMap[pubKey].followersCount,
|
||||
// followingCount: statsMap[pubKey].followingCount,
|
||||
// });
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.error('Error calculating and storing contact stats:', error);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
getContactStats$(pubKey: string): Observable<{ pubKey: string, totalContacts: number, followersCount: number, followingCount: number }> {
|
||||
if (!this.contactStatsMap[pubKey]) {
|
||||
this.contactStatsMap[pubKey] = new BehaviorSubject<{ pubKey: string, totalContacts: number, followersCount: number, followingCount: number }>({
|
||||
pubKey,
|
||||
totalContacts: 0,
|
||||
followersCount: 0,
|
||||
followingCount: 0,
|
||||
});
|
||||
// getContactStats$(pubKey: string): Observable<{ pubKey: string, totalContacts: number, followersCount: number, followingCount: number }> {
|
||||
// if (!this.contactStatsMap[pubKey]) {
|
||||
// this.contactStatsMap[pubKey] = new BehaviorSubject<{ pubKey: string, totalContacts: number, followersCount: number, followingCount: number }>({
|
||||
// pubKey,
|
||||
// totalContacts: 0,
|
||||
// followersCount: 0,
|
||||
// followingCount: 0,
|
||||
// });
|
||||
|
||||
this.calculateAndStoreAllContactStats();
|
||||
}
|
||||
return this.contactStatsMap[pubKey].asObservable();
|
||||
}
|
||||
// this.calculateAndStoreAllContactStats();
|
||||
// }
|
||||
// return this.contactStatsMap[pubKey].asObservable();
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
async getAllContactsPaginated(pubKey: string, page: number, pageSize: number): Promise<{ contacts: ContactEvent[], totalCount: number }> {
|
||||
try {
|
||||
const allContacts: ContactEvent[] = [];
|
||||
await this.contactsStore.iterate<ContactEvent, void>((contact, key) => {
|
||||
const [storedPubKey] = key.split(':');
|
||||
if (storedPubKey === pubKey) {
|
||||
allContacts.push(contact);
|
||||
}
|
||||
});
|
||||
// async getAllContactsPaginated(pubKey: string, page: number, pageSize: number): Promise<{ contacts: ContactEvent[], totalCount: number }> {
|
||||
// try {
|
||||
// const allContacts: ContactEvent[] = [];
|
||||
// await this.contactsStore.iterate<ContactEvent, void>((contact, key) => {
|
||||
// const [storedPubKey] = key.split(':');
|
||||
// if (storedPubKey === pubKey) {
|
||||
// allContacts.push(contact);
|
||||
// }
|
||||
// });
|
||||
|
||||
const totalCount = allContacts.length;
|
||||
const start = (page - 1) * pageSize;
|
||||
const end = start + pageSize;
|
||||
// const totalCount = allContacts.length;
|
||||
// const start = (page - 1) * pageSize;
|
||||
// const end = start + pageSize;
|
||||
|
||||
return {
|
||||
contacts: allContacts.slice(start, end),
|
||||
totalCount,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error retrieving paginated contacts for pubKey:', error);
|
||||
return { contacts: [], totalCount: 0 };
|
||||
}
|
||||
}
|
||||
// return {
|
||||
// contacts: allContacts.slice(start, end),
|
||||
// totalCount,
|
||||
// };
|
||||
// } catch (error) {
|
||||
// console.error('Error retrieving paginated contacts for pubKey:', error);
|
||||
// return { contacts: [], totalCount: 0 };
|
||||
// }
|
||||
// }
|
||||
|
||||
async getAllContacts(pubKey: string = ""): Promise<{ pubKey: string, contact: ContactEvent }[]> {
|
||||
try {
|
||||
const allContacts: { pubKey: string, contact: ContactEvent }[] = [];
|
||||
await this.contactsStore.iterate<ContactEvent, void>((contact, key) => {
|
||||
const [storedPubKey, contactId] = key.split(':');
|
||||
// async getAllContacts(pubKey: string = ""): Promise<{ pubKey: string, contact: ContactEvent }[]> {
|
||||
// try {
|
||||
// const allContacts: { pubKey: string, contact: ContactEvent }[] = [];
|
||||
// await this.contactsStore.iterate<ContactEvent, void>((contact, key) => {
|
||||
// const [storedPubKey, contactId] = key.split(':');
|
||||
|
||||
if (pubKey === "" || storedPubKey === pubKey) {
|
||||
allContacts.push({ pubKey: storedPubKey, contact });
|
||||
}
|
||||
});
|
||||
// if (pubKey === "" || storedPubKey === pubKey) {
|
||||
// allContacts.push({ pubKey: storedPubKey, contact });
|
||||
// }
|
||||
// });
|
||||
|
||||
return allContacts;
|
||||
} catch (error) {
|
||||
console.error('Error retrieving contacts:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
// return allContacts;
|
||||
// } catch (error) {
|
||||
// console.error('Error retrieving contacts:', error);
|
||||
// return [];
|
||||
// }
|
||||
// }
|
||||
|
||||
async getContactStats(pubKey: string): Promise<{ totalContacts: number, followersCount: number, followingCount: number }> {
|
||||
try {
|
||||
let totalContacts = 0;
|
||||
let followersCount = 0;
|
||||
let followingCount = 0;
|
||||
// async getContactStats(pubKey: string): Promise<{ totalContacts: number, followersCount: number, followingCount: number }> {
|
||||
// try {
|
||||
// let totalContacts = 0;
|
||||
// let followersCount = 0;
|
||||
// let followingCount = 0;
|
||||
|
||||
await this.contactsStore.iterate<ContactEvent, void>((contact, key) => {
|
||||
const [storedPubKey, contactId] = key.split(':');
|
||||
// await this.contactsStore.iterate<ContactEvent, void>((contact, key) => {
|
||||
// const [storedPubKey, contactId] = key.split(':');
|
||||
|
||||
if (storedPubKey === pubKey) {
|
||||
totalContacts++;
|
||||
// if (storedPubKey === pubKey) {
|
||||
// totalContacts++;
|
||||
|
||||
if (contact.isFollower) {
|
||||
followersCount++;
|
||||
} else {
|
||||
followingCount++;
|
||||
}
|
||||
}
|
||||
});
|
||||
// if (contact.isFollower) {
|
||||
// followersCount++;
|
||||
// } else {
|
||||
// followingCount++;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
return {
|
||||
totalContacts,
|
||||
followersCount,
|
||||
followingCount,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error retrieving contact stats for pubKey:', error);
|
||||
return { totalContacts: 0, followersCount: 0, followingCount: 0 };
|
||||
}
|
||||
}
|
||||
// return {
|
||||
// totalContacts,
|
||||
// followersCount,
|
||||
// followingCount,
|
||||
// };
|
||||
// } catch (error) {
|
||||
// console.error('Error retrieving contact stats for pubKey:', error);
|
||||
// return { totalContacts: 0, followersCount: 0, followingCount: 0 };
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
async removeAllContacts(pubKey: string): Promise<void> {
|
||||
try {
|
||||
const keysToRemove: string[] = [];
|
||||
// async removeAllContacts(pubKey: string): Promise<void> {
|
||||
// try {
|
||||
// const keysToRemove: string[] = [];
|
||||
|
||||
await this.contactsStore.iterate<ContactEvent, void>((contact, key) => {
|
||||
const [storedPubKey] = key.split(':');
|
||||
if (storedPubKey === pubKey) {
|
||||
keysToRemove.push(key);
|
||||
}
|
||||
});
|
||||
// await this.contactsStore.iterate<ContactEvent, void>((contact, key) => {
|
||||
// const [storedPubKey] = key.split(':');
|
||||
// if (storedPubKey === pubKey) {
|
||||
// keysToRemove.push(key);
|
||||
// }
|
||||
// });
|
||||
|
||||
for (const key of keysToRemove) {
|
||||
await this.contactsStore.removeItem(key);
|
||||
}
|
||||
// for (const key of keysToRemove) {
|
||||
// await this.contactsStore.removeItem(key);
|
||||
// }
|
||||
|
||||
await this.contactsStore.clear();
|
||||
this.contactStatsSubject.next({ totalContacts: 0, followersCount: 0, followingCount: 0 });
|
||||
// await this.contactsStore.clear();
|
||||
// this.contactStatsSubject.next({ totalContacts: 0, followersCount: 0, followingCount: 0 });
|
||||
|
||||
this.contactsSubject.next({ pubKey, contacts: [] });
|
||||
await this.setUpdateHistory('contacts');
|
||||
} catch (error) {
|
||||
console.error('Error removing all contacts for pubKey:', error);
|
||||
}
|
||||
}
|
||||
// this.contactsSubject.next({ pubKey, contacts: [] });
|
||||
// await this.setUpdateHistory('contacts');
|
||||
// } catch (error) {
|
||||
// console.error('Error removing all contacts for pubKey:', error);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// --------------------- profiles Metadata Methods ---------------------
|
||||
@@ -722,26 +722,26 @@ export class StorageService {
|
||||
}
|
||||
}
|
||||
|
||||
private async loadAllContactsFromDB(pubKey: string = ""): Promise<void> {
|
||||
try {
|
||||
const contacts = await this.getAllContacts(pubKey);
|
||||
if (contacts.length > 0) {
|
||||
const groupedContacts: { [pubKey: string]: ContactEvent[] } = {};
|
||||
// private async loadAllContactsFromDB(pubKey: string = ""): Promise<void> {
|
||||
// try {
|
||||
// const contacts = await this.getAllContacts(pubKey);
|
||||
// if (contacts.length > 0) {
|
||||
// const groupedContacts: { [pubKey: string]: ContactEvent[] } = {};
|
||||
|
||||
for (const contact of contacts) {
|
||||
if (!groupedContacts[contact.pubKey]) {
|
||||
groupedContacts[contact.pubKey] = [];
|
||||
}
|
||||
groupedContacts[contact.pubKey].push(contact.contact);
|
||||
}
|
||||
for (const pubKey in groupedContacts) {
|
||||
this.contactsSubject.next({ pubKey, contacts: groupedContacts[pubKey] });
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading contacts from DB:', error);
|
||||
}
|
||||
}
|
||||
// for (const contact of contacts) {
|
||||
// if (!groupedContacts[contact.pubKey]) {
|
||||
// groupedContacts[contact.pubKey] = [];
|
||||
// }
|
||||
// groupedContacts[contact.pubKey].push(contact.contact);
|
||||
// }
|
||||
// for (const pubKey in groupedContacts) {
|
||||
// this.contactsSubject.next({ pubKey, contacts: groupedContacts[pubKey] });
|
||||
// }
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.error('Error loading contacts from DB:', error);
|
||||
// }
|
||||
// }
|
||||
|
||||
private async loadAllChatEventsFromDB(): Promise<void> {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user