Skip to content

Commit

Permalink
Add send message method
Browse files Browse the repository at this point in the history
  • Loading branch information
miladsoft committed Sep 21, 2024
1 parent 9e7d222 commit 477eb3a
Show file tree
Hide file tree
Showing 7 changed files with 439 additions and 356 deletions.
565 changes: 317 additions & 248 deletions src/app/components/chat/chat.service.ts

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/app/components/chat/chats/chats.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ export class ChatsComponent implements OnInit, OnDestroy {

this._changeDetectorRef.markForCheck();
});
}

}

/**
* On destroy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,14 @@
class="angor-mat-dense angor-mat-rounded angor-mat-bold ml-4 w-full"
subscriptSizing="dynamic"
>
<textarea
<textarea class="max-h-20"
matInput
cdkTextareaAutosize
#messageInput
></textarea>
</mat-form-field>
<div class="my-px ml-4 flex h-11 items-center">
<button mat-icon-button>
<button mat-icon-button (click)="sendMessage()">
<mat-icon
[svgIcon]="'heroicons_outline:paper-airplane'"
></mat-icon>
Expand Down
55 changes: 18 additions & 37 deletions src/app/components/chat/conversation/conversation.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,13 @@ export class ConversationComponent implements OnInit, OnDestroy {
drawerOpened: boolean = false;
private _unsubscribeAll: Subject<any> = new Subject<any>();

/**
* Constructor
*/
constructor(
private _changeDetectorRef: ChangeDetectorRef,
private _chatService: ChatService,
private _angorMediaWatcherService: AngorMediaWatcherService,
private _ngZone: NgZone
) {}





/**
* Resize on 'input' and 'ngModelChange' events
*
* @private
*/
@HostListener('input')
@HostListener('ngModelChange')
private _resizeMessageInput(): void {
Expand All @@ -93,13 +81,6 @@ export class ConversationComponent implements OnInit, OnDestroy {
});
}





/**
* On init
*/
ngOnInit(): void {

this._chatService.chat$
Expand Down Expand Up @@ -127,18 +108,12 @@ export class ConversationComponent implements OnInit, OnDestroy {
});
}

/**
* On destroy
*/
ngOnDestroy(): void {

this._unsubscribeAll.next(null);
this._unsubscribeAll.complete();
}

/**
* Open the contact info
*/
openContactInfo(): void {

this.drawerOpened = true;
Expand All @@ -147,9 +122,6 @@ export class ConversationComponent implements OnInit, OnDestroy {
this._changeDetectorRef.markForCheck();
}

/**
* Reset the chat
*/
resetChat(): void {
this._chatService.resetChat();

Expand All @@ -160,9 +132,6 @@ export class ConversationComponent implements OnInit, OnDestroy {
this._changeDetectorRef.markForCheck();
}

/**
* Toggle mute notifications
*/
toggleMuteNotifications(): void {

this.chat.muted = !this.chat.muted;
Expand All @@ -171,12 +140,24 @@ export class ConversationComponent implements OnInit, OnDestroy {
this._chatService.updateChat(this.chat.id, this.chat).subscribe();
}

/**
* Track by function for ngFor loops
*
* @param index
* @param item
*/
sendMessage(): void {
const messageContent = this.messageInput.nativeElement.value.trim();

if (!messageContent) {
console.warn('Cannot send an empty message.');
return;
}

this._chatService.sendPrivateMessage(messageContent)
.then(() => {
this.messageInput.nativeElement.value = '';
console.log('Message sent successfully.');
})
.catch((error) => {
console.error('Failed to send message:', error);
});
}

trackByFn(index: number, item: any): any {
return item.id || index;
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/chat/new-chat/new-chat.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@
) {
<div
class="text-secondary sticky top-0 z-10 -mt-px border-b border-t bg-gray-100 px-6 py-1 font-medium uppercase dark:bg-gray-900 md:px-8"
>
(click)="openChat(contact)">
{{ contact?.name?.charAt(0) ?? '' }}
</div>
}

<!-- Contact -->
<div
class="z-20 flex cursor-pointer items-center border-b px-6 py-4 dark:hover:bg-hover hover:bg-gray-100 md:px-8"
>
(click)="openChat(contact)" >
<div
class="flex h-10 w-10 flex-0 items-center justify-center overflow-hidden rounded-full"
>
Expand Down
38 changes: 14 additions & 24 deletions src/app/components/chat/new-chat/new-chat.component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Router } from '@angular/router';
import {
ChangeDetectionStrategy,
Component,
Expand All @@ -11,7 +12,7 @@ import { MatIconModule } from '@angular/material/icon';
import { MatDrawer } from '@angular/material/sidenav';
import { ChatService } from 'app/components/chat/chat.service';
import { Contact } from 'app/components/chat/chat.types';
import { Subject, takeUntil } from 'rxjs';
import { catchError, Subject, takeUntil, throwError } from 'rxjs';

@Component({
selector: 'chat-new-chat',
Expand All @@ -26,46 +27,35 @@ export class NewChatComponent implements OnInit, OnDestroy {
contacts: Contact[] = [];
private _unsubscribeAll: Subject<any> = new Subject<any>();

/**
* Constructor
*/
constructor(private _chatService: ChatService) {}
constructor(private _chatService: ChatService, private router: Router) {}





/**
* On init
*/
ngOnInit(): void {

this._chatService.contacts$
.pipe(takeUntil(this._unsubscribeAll))
.subscribe((contacts: Contact[]) => {
this.contacts = contacts;
});
}

/**
* On destroy
*/
ngOnDestroy(): void {

this._unsubscribeAll.next(null);
this._unsubscribeAll.complete();
}

openChat(contact: Contact): void {
this._chatService.getChatById(contact.pubKey).pipe(

catchError((error) => {
console.error(error);
const parentUrl = this.router.url.split('/').slice(0, -1).join('/');
this.router.navigateByUrl(parentUrl);
return throwError(error);
})
).subscribe();

this.drawer.close();
}


/**
* Track by function for ngFor loops
*
* @param index
* @param item
*/
trackByFn(index: number, item: any): any {
return item.id || index;
}
Expand Down
126 changes: 84 additions & 42 deletions src/app/services/signer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,56 +208,48 @@ export class SignerService {
}
}

async signEventWithExtension(unsignedEvent: UnsignedEvent): Promise<Event> {
const gt = globalThis as any;
if (gt.nostr) {
const signedEvent = await gt.nostr.signEvent(unsignedEvent);
return signedEvent;
} else {
throw new Error("Tried to sign event with extension but failed");
}
}

// Messaging (NIP-04)
async decryptMessageWithExtension(encryptedContent: string, senderPubKey: string): Promise<string> {
try {
const gt = globalThis as any;
const decryptedMessage = await gt.nostr.nip04.decrypt(senderPubKey, encryptedContent);
return decryptedMessage;
} catch (error) {
console.error('Error decrypting message with extension:', error);
throw new Error('Failed to decrypt message with Nostr extension.');

// Messaging (NIP-04)
async decryptMessageWithExtension(encryptedContent: string, senderPubKey: string): Promise<string> {
try {
const gt = globalThis as any;
const decryptedMessage = await gt.nostr.nip04.decrypt(senderPubKey, encryptedContent);
return decryptedMessage;
} catch (error) {
console.error('Error decrypting message with extension:', error);
throw new Error('Failed to decrypt message with Nostr extension.');
}
}
}


async encryptMessageWithExtension(content: string, pubKey: string): Promise<string> {
const gt = globalThis as any;
const encryptedMessage = await gt.nostr.nip04.encrypt(pubKey, content);
return encryptedMessage;
}
async encryptMessageWithExtension(content: string, pubKey: string): Promise<string> {
const gt = globalThis as any;
const encryptedMessage = await gt.nostr.nip04.encrypt(pubKey, content);
return encryptedMessage;
}

async encryptMessage(privateKey: string, recipientPublicKey: string, message: string): Promise<string> {
console.log(message);
try {
const encryptedMessage = await nip04.encrypt(privateKey, recipientPublicKey, message);
return encryptedMessage;
} catch (error) {
console.error('Error encrypting message:', error);
throw error;
async encryptMessage(privateKey: string, recipientPublicKey: string, message: string): Promise<string> {
console.log(message);
try {
const encryptedMessage = await nip04.encrypt(privateKey, recipientPublicKey, message);
return encryptedMessage;
} catch (error) {
console.error('Error encrypting message:', error);
throw error;
}
}
}

// NIP-04: Decrypting Direct Messages
async decryptMessage(privateKey: string, senderPublicKey: string, encryptedMessage: string): Promise<string> {
try {
const decryptedMessage = await nip04.decrypt(privateKey, senderPublicKey, encryptedMessage);
return decryptedMessage;
} catch (error) {
console.error('Error decrypting message:', error);
throw error;
// NIP-04: Decrypting Direct Messages
async decryptMessage(privateKey: string, senderPublicKey: string, encryptedMessage: string): Promise<string> {
try {
const decryptedMessage = await nip04.decrypt(privateKey, senderPublicKey, encryptedMessage);
return decryptedMessage;
} catch (error) {
console.error('Error decrypting message:', error);
throw error;
}
}
}



Expand All @@ -280,6 +272,56 @@ export class SignerService {
return signedEvent;
}




async signEventWithExtension(unsignedEvent: UnsignedEvent): Promise<Event> {
const gt = globalThis as any;
if (gt.nostr) {
const signedEvent = await gt.nostr.signEvent(unsignedEvent)
return signedEvent;
} else {
throw new Error("Tried to sign event with extension but failed");
}
}

async signDMWithExtension(pubkey: string, content: string): Promise<string> {
const gt = globalThis as any;
if (gt.nostr && gt.nostr.nip04?.encrypt) {
return await gt.nostr.nip04.encrypt(pubkey, content)
}
throw new Error("Failed to Sign with extension");
}

async decryptDMWithExtension(pubkey: string, ciphertext: string): Promise<string> {
const gt = globalThis as any;
if (gt.nostr && gt.nostr.nip04?.decrypt) {
const decryptedContent = await gt.nostr.nip04.decrypt(pubkey, ciphertext)
.catch((error: any) => {
return "*Failed to Decrypted Content*"
});
return decryptedContent;
}
return "Attempted Nostr Window decryption and failed."
}

async decryptWithPrivateKey(pubkey: string, ciphertext: string, password: string): Promise<string> {
try {
// Get the stored private key in hex format
let privateKey = await this.getSecretKey("password");

// Ensure the private key is in Uint8Array format
const privateKeyUint8Array = new Uint8Array(Buffer.from(privateKey, 'hex'));

// Decrypt the message using the private key and public key
return await nip04.decrypt(privateKeyUint8Array, pubkey, ciphertext);
} catch (error) {
console.error("Error during decryption: ", error);
return "*Failed to Decrypted Content*";
}
}


public async isUsingExtension(): Promise<boolean> {
const globalContext = globalThis as any;
if (globalContext.nostr && globalContext.nostr.getPublicKey) {
Expand Down

0 comments on commit 477eb3a

Please sign in to comment.