pazznetwork / ngx-chat Goto Github PK
View Code? Open in Web Editor NEWAngular XMPP Client & Chat UI
License: Other
Angular XMPP Client & Chat UI
License: Other
supportsFeature(jid: string, feature: string): Promise<boolean> {
return new Promise((resolve, reject) => {
this.servicesInitialized$.pipe(first(value => !!value)).subscribe(async () => {
try {
const service = this.resourceCache[jid] || await this.discoverServiceInformation(jid);
if (!service) {
reject(new Error('no service found for jid ' + jid));
}
const results = this.resourceCache[jid].features.filter(resource => resource.indexOf(feature) >= 0);
resolve(results.length > 0);
} catch (e) {
reject(e);
}
});
});
}
I compiled new version of ejabberd and I've made changes in configuration so I know now nothing about anything :) If I see any errors I don't know what is responsible for them.
But your function is throwing errors. I think this line is responsible:
const results = this.resourceCache[jid].features.filter(resource => resource.indexOf(feature) >= 0);
It should be:
const results = service.features.filter(resource => resource.indexOf(feature) >= 0);
Hello,
i have been trying lately to build the lib with the command provided in the readme file :
ng build @pazznetwork/ngx-chat --watch
but i still getting this error
ERROR: projects/pazznetwork/ngx-chat/src/lib/services/adapters/xmpp/plugins/service-discovery.plugin.ts:145:9 - error TS2322: Type '{ identities: { [attrName: string]: any; }[]; features: any[]; jid: string; }' is not assignable to type 'Service'.
Types of property 'identities' are incompatible.
Type '{ [attrName: string]: any; }[]' is not assignable to type 'Identity[]'.
Type '{ [attrName: string]: any; }' is missing the following properties from type 'Identity': category, type
145 return serviceInformation;
~~~~~~~~~~~~~~~~~~~~~~~~~~
projects/pazznetwork/ngx-chat/src/lib/services/adapters/xmpp/plugins/multi-user-chat.plugin.ts:336:9 - error TS2322: Type '{ [attrName: string]: any; }[]' is not assignable to type 'RoomSummary[]'.
Type '{ [attrName: string]: any; }' is missing the following properties from type 'RoomSummary': jid, name
336 return roomElements.map(room => room.attrs);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An unhandled exception occurred: projects/pazznetwork/ngx-chat/src/lib/services/adapters/xmpp/plugins/service-discovery.plugin.ts:145:9 - error TS2322: Type '{ identities: { [attrName: string]: any; }[]; features: any[]; jid: string; }' is not assignable to type 'Service'.
Types of property 'identities' are incompatible.
Type '{ [attrName: string]: any; }[]' is not assignable to type 'Identity[]'.
Type '{ [attrName: string]: any; }' is missing the following properties from type 'Identity': category, type
145 return serviceInformation;
~~~~~~~~~~~~~~~~~~~~~~~~~~
projects/pazznetwork/ngx-chat/src/lib/services/adapters/xmpp/plugins/multi-user-chat.plugin.ts:336:9 - error TS2322: Type '{ [attrName: string]: any; }[]' is not assignable to type 'RoomSummary[]'.
Type '{ [attrName: string]: any; }' is missing the following properties from type 'RoomSummary': jid, name
336 return roomElements.map(room => room.attrs);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
First message to chat room generates well known ExpressionChangedAfterItHasBeenCheckedError
error:
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngIf: [object Object]'. Current value: 'ngIf: true'.
at viewDebugError (core.js:17857)
at expressionChangedAfterItHasBeenCheckedError (core.js:17845)
at checkBindingNoChanges (core.js:18045)
at checkNoChangesNodeInline (core.js:27623)
at checkNoChangesNode (core.js:27612)
at debugCheckNoChangesNode (core.js:28216)
at debugCheckDirectivesFn (core.js:28144)
at Object.eval [as updateDirectives] (AppComponent.html:77)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:28133)
at checkNoChangesView (core.js:27511)
Hey Trampi, I will suggest some changes now, but keep in mind I'm not a professional programmer, so look at my suggestions very carefully, as they may harm your app in places I don't see.
You can eliminate ExpressionChangedAfterItHasBeenCheckedError
error if you subscribe to contacts.
I made these changes:
app.component.ts
import { Component, Inject, OnDestroy } from '@angular/core';
...
public contacts$: Observable<Contact[]> = this.chatService.contactsSubscribed$;
public contacts: Contact[];
public subscription;
...
chatBackgroundNotificationService.enable();
this.subscription = this.contacts$.subscribe(contacts => {
this.contacts = contacts;
});
...
onToggleContactList() {
if (this.contacts$ === this.chatService.contactsSubscribed$) {
this.contacts$ = of([
this.contactFactory.createContact('user@host', 'user1'),
this.contactFactory.createContact('user2@host', 'user2'),
]);
} else {
this.contacts$ = this.chatService.contactsSubscribed$;
}
}
...
ngOnDestroy() {
this.subscription.unsubscribe();
}
app.component.html:
<ng-container *ngIf="contacts.length > 0; else messagesComponentInformation">
<ngx-chat-message-list [contact]="contacts[0]"
[showAvatars]="true"></ngx-chat-message-list>
<ngx-chat-message-input [contact]="contacts[0]"></ngx-chat-message-input>
</ng-container>
...
<ngx-chat rosterState="shown" [contacts]="contacts$"></ngx-chat>
I have upgraded your app to Angular 8 and is working after some minor changes.
I removed @angular/http from dependencies.
"dependencies": {
"@angular/animations": "~8.0.0",
"@angular/cdk": "~8.0.0",
"@angular/common": "~8.0.0",
"@angular/compiler": "~8.0.0",
"@angular/core": "~8.0.0",
"@angular/forms": "~8.0.0",
"@angular/platform-browser": "~8.0.0",
"@angular/platform-browser-dynamic": "~8.0.0",
"@angular/router": "~8.0.0",
"@types/ltx": "^2.6.3",
"@xmpp/client": "^0.3.0",
"core-js": "^2.5.4",
"rxjs": "~6.4.0",
**"tslib": "^1.9.3",** <-- moved from devDependencies
"zone.js": "~0.9.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.800.1",
"@angular-devkit/build-ng-packagr": "^0.800.1",
"@angular/cli": "~8.0.1",
"@angular/compiler-cli": "~8.0.0",
"@angular/language-service": "~8.0.0",
"@commitlint/cli": "^7.2.1",
"@commitlint/config-angular": "^7.1.2",
"@compodoc/compodoc": "^1.1.3",
"@types/jasmine": "~3.3.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^10.0.0",
"codelyzer": "^5.0.0",
"concat-files": "^0.1.1",
"conventional-changelog-cli": "^2.0.12",
"coveralls": "^3.0.2",
"debug": "^4.1.1",
"glob": "^7.1.2",
"husky": "^1.1.3",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0",
"ng-packagr": "^3.0.6",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tsickle": "^0.29.0",
"tslint": "~5.15.0",
"typescript": "~3.4.3",
"webpack-bundle-analyzer": "^2.13.1"
},
I made these changes in your code (specification of @ViewChild was changed)
https://blog.ninja-squad.com/2019/05/29/what-is-new-angular-8.0/
This is not a good change, but bad practice !!
export interface Service {
jid: string;
identities: any; // Identity[];
features: string[];
}
After these changes your app is working without errors I can notice, but my tests were very limited. I simply logged in, sent few messages, subscribe to room etc. So errors may surface in other places.
Warning:
I have upgraded devDependencies testing libraries, so they are now the same as when you generate new app in Angular 8 with: ng new test1
So your tests won't work probably without some upgrade.
My node version is 10.16.0 => "@types/node": "^10.0.0"
Node 12 is good too, app is working without errors, after upgrade "@types/node" to newest 12.0.4 version.
Fresh install, npm install.
Login, List all rooms, join
Then when I send a message I have ExpressionChangedAfterItHasBeenCheckedError:
AppComponent.html:77 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngIf: [object Object]'. Current value: 'ngIf: false'.
The only difference in my code is additional check in ng-container:
<ng-container *ngIf="this.chatService.state$.getValue() === 'online' && (this.chatService.contactsSubscribed$ | async).length > 0; else messagesComponentInformation">
Without this check ((this.chatService.contactsSubscribed$ | async).length > 0
) there is another error.
In core/plugin.ts there is a typo:
afterReceiveMessage(message: Message, messageStanza: MessageWithBodyStanza, MessageReceivedEvent: MessageReceivedEvent): void;
should be messageReceivedEvent: MessageReceivedEvent
probably.
Update 25/04/2020
Additional check in ng-container I proposed earlier ((this.chatService.contactsSubscribed$ | async).length > 0
) is not good. Eliminates one error but creates another. Best solution is presented below. Additional check (this.chatService.contactsSubscribed$ | async)[0]
eliminates all errors:
<div>
<h2>Custom component for a chat session</h2>
<ng-container *ngIf="(this.chatService.state$ | async) === 'online' && (this.chatService.contactsSubscribed$ | async)[0]; else messagesComponentInformation">
<ngx-chat-message-list [contact]="(this.chatService.contactsSubscribed$ | async)[0]"
[showAvatars]="true"></ngx-chat-message-list>
<ngx-chat-message-input [contact]="(this.chatService.contactsSubscribed$ | async)[0]"></ngx-chat-message-input>
</ng-container>
<ng-template #messagesComponentInformation>You need to be logged in and have contacts to see this component</ng-template>
</div>
how integrate in our admin panel
Angular CLI: 1.7.4
Node: 10.16.0
OS: linux x64
Angular: 5.2.11
as per the given instructions i ran the application but application is not executing
The problem is because app doesn't process info nodes: https://xmpp.org/extensions/xep-0030.html#info-nodes
private async discoverServices() {
const serviceListResponsePromise = this.chatAdapter.chatConnectionService.sendIq(
new QueryStanzaBuilder(
ServiceDiscoveryPlugin.DISCO_ITEMS, this.chatAdapter.chatConnectionService.userJid.domain).toStanza()
);
const serviceDomains = (await serviceListResponsePromise)
.getChild('query').getChildren('item').map(itemNode => itemNode.attrs.jid);
const discoveredServices = await Promise.all(serviceDomains.map(serviceDomain => this.discoverServiceInformation(serviceDomain)));
this.services.push(...discoveredServices);
}
Code above maps according to jid
, but info nodes in my case (or maybe always, I don't know) have the same jid
.
My response from server:
<iq xmlns="jabber:client" xml:lang="en" to="[email protected]/30959486515595480201154" from="pc17.home" type="result" id="info1">
<query xmlns="http://jabber.org/protocol/disco#items">
<item jid="conference.pc17.home"/>
<item jid="proxy.pc17.home"/>
<item jid="pubsub.pc17.home"/>
<item jid="upload.pc17.home"/>
<item node="announce" name="Announcements" jid="pc17.home"/>
<item node="config" name="Configuration" jid="pc17.home"/>
<item node="user" name="User Management" jid="pc17.home"/>
<item node="online users" name="Online Users" jid="pc17.home"/>
<item node="all users" name="All Users" jid="pc17.home"/>
<item node="outgoing s2s" name="Outgoing s2s Connections" jid="pc17.home"/>
<item node="running nodes" name="Running Nodes" jid="pc17.home"/>
<item node="stopped nodes" name="Stopped Nodes" jid="pc17.home"/>
</query>
</iq>
const serviceDomains = (await serviceListResponsePromise)
.getChild('query').getChildren('item').map(itemNode => itemNode.attrs.jid);
serviceDomains
result in my case:
Array(12) 0: "conference.pc17.home" 1: "proxy.pc17.home" 2: "pubsub.pc17.home" 3: "upload.pc17.home" 4: "pc17.home" 5: "pc17.home" 6: "pc17.home" 7: "pc17.home" 8: "pc17.home" 9: "pc17.home" 10: "pc17.home" 11: "pc17.home"
Then there is:
const discoveredServices = await Promise.all(serviceDomains.map(serviceDomain => this.discoverServiceInformation(serviceDomain)));
which checks many times the same value "pc17.home"
Because program is working in such a way function discoverServerFeatures()
produces this.services
variable, which contain the same values in array. But findService
function rejects results if length > 1:
findService(category: string, type: string): Promise<Service> {
return new Promise((resolve, reject) => {
this.servicesInitialized$.pipe(first(value => !!value)).subscribe(() => {
const results = this.services.filter(service =>
service.identities.filter(identity => identity.category === category && identity.type === type).length > 0
);
if (results.length === 0) {
reject(`no service matching category ${category} and type ${type} found!`);
} else if (results.length > 1) {
reject(`multiple services matching category ${category} and type ${type} found! ${JSON.stringify(results)}`);
} else {
return resolve(results[0]);
}
});
});
}
My specific problem: if category === "pubsub"
and type === "pep"
findService
returns incorrect answer.
Hi
I have the latest ejabberd server and when i try the demo site, it just wont connect. I can see the connection coming through to the server, but it does not progress and keeps retrying....
Any ideas?
We tried this component with Tigase but it throws at least two different types of errors in the browser console
Can we have ngx-chat to support Tigase as well please?
Before join:
polityka (0): [email protected]
After join:
polityka (0): [email protected]
Should be:
polityka (1): [email protected]
You have to click "List all rooms" to see updated names, but it should definitely update automatically. It's important to see in real time number of users in rooms.
Is this library supposed to work with Angular 11? I get the following errors
Error: node_modules/@pazznetwork/ngx-chat/lib/ngx-chat.module.d.ts:2:22 - error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class.
This likely means that the library (@pazznetwork/ngx-chat/lib/ngx-chat.module) which declares NgxChatModule has not been processed correctly by ngcc, or is not compatible with Angular Ivy. Check if a newer version of the library is available, and update if so. Also consider checking with the library's authors to see if the library is expected to be compatible with Ivy.
2 export declare class NgxChatModule {
~~~~~~~~~~~~~
src/app/chat/components/chat/chat.component.html:3:1 - error NG8001: 'ngx-chat' is not a known element:
1. If 'ngx-chat' is an Angular component, then verify that it is part of this module.
2. If 'ngx-chat' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
App 0.9.0 won't compile unless you add
export * from './lib/components/chat-room-messages/chat-room-messages.component';
export * from './lib/components/chat-filedrop/file-drop.component';
export * from './lib/directives/links.directive';
in public-api.ts
In multi-user-chat.component.html
vscode shows two errors (code compile and works anyway, so it is annoyance only, not an error):
'ngx-chat-room-messages' is not a known element
'ngx-chat-message-input' is not a known element
Full vscode error message from 1:
`'ngx-chat-room-messages' is not a known element:
In multi-user-chat-component.ts
vscode shows one error:
Can't resolve all parameters for MultiUserChatComponent in /home/leszek/dev/tests/ngx-chat-angular9/src/app/multi-user-chat/multi-user-chat.component.ts: (?).
It looks like components are exported, yet vscode complains.
I don't know how to correct it.
Hello Trumpi!
Fresh git clone, npm install, change in ngx-chat-imports.ts to development:
export * from '../../projects/pazznetwork/ngx-chat/src/public_api';
If you run app (npm start) and log in, (contacts | async).length
throws error
This error disappears if you change line 12 in roster-list.component.html to:
'<ng-container *ngIf="(contacts | async)?.length > 0">'
atm. avatars are always squashed into the 1:1 ratio.
Hello,
i have a Problem with loading messages. As a XMPP-Server i use Openfire 4.6.0. When i load messages from a room (N to N Chat) i created and joined it works like a charm. All messages are saved and then loaded, even after i close my app. But when i try to load messages i send to a contact (1 to 1 Chat) just minutes ago, and reload my app, all messages are gone.
So i tried to enable the Monitoring Service Plugin for Openfire, and it does archive all messages i send. When i then try to call the function loadCompleteHistory() i get the "feature-not-implemented" error.
core.js:4197 ERROR Error: Uncaught (in promise): <iq xmlns="jabber:client" type="error" id="1606997503937" to="alice@d715be968047/3cbsrauy6m"><error code="501" type="cancel"><feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>
Heres how i call the functions in angular:
async loadAllArchivedMessages() { this.ngxChatService.loadCompleteHistory().then(async () => { await Promise.resolve(); });
loadAllArchivedMessages() { this.chatService.loadAllArchivedMessages().then(() => console.log("hello")); }
It does print the "hello", so the Promise does resolve, but the archived messages do not get loaded. Is there something that i do wrong, or is that a known issue?
This is the same error I reported earlier, my mistake. So I'm closing this issue.
ERROR in projects/pazznetwork/ngx-chat/src/lib/services/adapters/xmpp/plugins/service-discovery.plugin.ts(109,9): error TS2322: Type '{ identities: { [attrName: string]: any; }[]; features: any[]; jid: string; }' is not assignable to type 'Service'.
Types of property 'identities' are incompatible.
Type '{ [attrName: string]: any; }[]' is not assignable to type 'Identity[]'.
Type '{ [attrName: string]: any; }' is not assignable to type 'Identity'.
Property 'category' is missing in type '{ [attrName: string]: any; }'.
ngx-chat broke tests in another project because of zoning issues with protractor and the xmpp socket. To prevent that in the future, e2e tests should be added.
Could you please add your ejabberd.yml to documentation?
I'm trying - with partial success - to view your ngx-chat, but MUC doesn't work (individual chat works very well). Pidgin client see rooms on my ejabberd server, but your app doesn't.
I guess maybe if I update my ejabberd server configuration according to your guidelines, MUC will work.
I have ejabberd 19.02.131, compiled from source.
Update
I made some tests and here are my observations:
After I join room ([email protected]/test) there are unknown stanzas reported:
ChatService: unknown stanza <=presence xmlns="jabber:client" xml:lang="en" to="[email protected]/121400852556687662463106" from="[email protected]/leszek"=><=c xmlns="http://jabber.org/protocol/caps" node="http://pidgin.im/" hash="sha-1" ver="AcN1/PEN8nq7AHD+9jpxMV4U6YM=" ext="voice-v1 camera-v1 video-v1"/=><=x xmlns="vcard-temp:x:update"/=><=x xmlns="http://jabber.org/protocol/muc#user"=><=item role="participant" affiliation="none"/=><=/x=><=priority=>1<=/priority=><=/presence=>
where [email protected]/leszek is pidgin user
Interesting that roster sees room, but when I try to send message prom pidgin your app shows error:
ChatService: error handling stanza in MultiUserChatPlugin Error: no room with given jid found: [email protected]
ChatService: unknown stanza <= (message xmlns="jabber:client" xml:lang="en" to="[email protected]/121400852556687662463106" from="[email protected]/leszek" type="groupchat" id="purplefeb22741")(archived by="[email protected]" id="1559202866878904" xmlns="urn:xmpp:mam:tmp"/)(stanza-id by="[email protected]" id="1559202866878904" xmlns="urn:xmpp:sid:0"/)(body)bbb(/body)(/message)
Looks like ejabberd doesn't stricly follow xep-0045 specifications and that's why your app doesn't recognize important presence stanzas:
ChatService: unknown stanza <= (presence xmlns="jabber:client" xml:lang="en" to="[email protected]/121400852556687662463106" from="[email protected]/test")(x xmlns="vcard-temp:x:update"/)(x xmlns="http://jabber.org/protocol/muc#user")(item jid="[email protected]/121400852556687662463106" role="participant" affiliation="none"/)(status code="110"/)(/x)(/presence)
and
ChatService: unknown stanza <= (message xmlns="jabber:client" to="[email protected]/121400852556687662463106" from="[email protected]" type="groupchat")(subject/)(/message)
Update2
Could you please check joinRoomInternal function of MultiUserChatPlugin?
Are you sure it should work?
const roomJoinedPromise = new Promise(resolve => this.roomJoinPromises[occupantJid.toString()] = resolve);
Does ngx-chat support https rather than wss
My roomResponse
doesn't have fin
child, so while
loop is never executed.
I'm using ejabberd 19.09.2, PostgreSQL database. There is archive table and there are messages in it.
I don't see fin
child in XEP-0030 Service Discovery specification.
my roomResponse
:
Element {name: "iq", parent: null, children: Array(1), attrs: {…}}
name: "iq"
parent: null
children: Array(1)
0: Element
name: "query"
parent: Element {name: "iq", parent: null, children: Array(1), attrs: {…}}
children: Array(1)
0: Element
name: "item"
parent: Element {name: "query", parent: Element, children: Array(1), attrs: {…}}
children: []
attrs: {name: "polityka (0)", jid: "[email protected]"}
__proto__: Element
length: 1
__proto__: Array(0)
attrs: {xmlns: "http://jabber.org/protocol/disco#items"}
__proto__: Element
length: 1
__proto__: Array(0)
attrs:
xmlns: "jabber:client"
xml:lang: "en"
to: "[email protected]/64890716320141744352018"
from: "conference.pc17.home"
type: "result"
id: "1581949131466"
__proto__: Object
__proto__: Element
I am Trying to include group chat. but my room array is always empty. Please help me on this. I can access my rooms via other xmpp clients. But here it is not loading.
Hello,
I've been having some issues with the message state plugin.
The states switch back and forth in a weird way when the users "A" and "B" are in the active window - it looks like "something is wrong" in the user experience. The issue goes like this:
Issue Description
Contact A, sends a message to user B, both are in the active (open) window, now this happens:
I've found that there are several things going on in the "local" state fo the messages (the jidToMessageStateDate) and in the "server" the persistent "remote" state pubsub node... along with the notification message stanza being sent. Well...
... actually I happen to come with a "fix":
BUG:
"MESSAGE STATE BOUNCING" From "sent" to "seen" to "sent" to "seen"
SOLUTION:
Compare local dates vs remote dates
Only update local dates if remote dates are greater
LOCAL DATE > REMOTE DATE ? YES = LEAVE DATE AS IS : NO = UPDATE WITH REMOTE ONE;
Do it for each date (sent, received, seen)
Notes: By "remote dates" I mean the ones that are retrieved from the pubsub.
CODE
message-state.plugin.ts
// .
// . (more code before)
// .
private processPubSub(itemElement: Element[]) {
const results = {} as JidToMessageStateDate;
if (itemElement.length === 1) {
for (const lastReadEntry of itemElement[0].getChild(wrapperNodeName).getChildren(nodeName)) {
const {lastRecipientReceived, lastRecipientSeen, lastSent, jid} = lastReadEntry.attrs;
const localState = this.getContactMessageState(jid);
const remoteState = {
lastSent: new Date(+lastSent || 0),
lastRecipientReceived: new Date(+lastRecipientReceived || 0),
lastRecipientSeen: new Date(+lastRecipientSeen || 0)
};
const isLocalSentNewer = localState.lastSent.getTime() > remoteState.lastSent.getTime();
const isLocalReceivedNewer = localState.lastRecipientReceived.getTime() > remoteState.lastRecipientReceived.getTime();
const isLocalSeenNewer = localState.lastRecipientSeen.getTime() > remoteState.lastRecipientSeen.getTime();
results[jid] = {
lastSent: isLocalSentNewer ? localState.lastSent : remoteState.lastSent,
lastRecipientReceived: isLocalReceivedNewer ? localState.lastRecipientReceived : remoteState.lastRecipientReceived,
lastRecipientSeen: isLocalSeenNewer ? localState.lastRecipientSeen : remoteState.lastRecipientSeen,
};
}
}
this.jidToMessageStateDate = results;
}
// .
// . (more code before)
// .
public getContactMessageState(contactJid: string) {
if (!this.jidToMessageStateDate[contactJid]) {
this.jidToMessageStateDate[contactJid] = {
lastRecipientReceived: new Date(0),
lastRecipientSeen: new Date(0),
lastSent: new Date(0),
};
}
return this.jidToMessageStateDate[contactJid];
}
Now. That fixes the "bouncing", and gives better experience...
I haven't fully tested it yet, but it seems to work.
BUT THERE'S ANOTHER ISSUE LEFT:
Message states not reported to offline users
I'm working on it. You can reproduce the issue like this:
The issue is because the plugin right now is designed to work while the Contacts are ONLINE.
And the fix needs adjustments to the PubSub plugin for broader support of the XEP.
The idea is to allow contacts in the roster "read" the node from their peers (subscribe to the node) and get the status dates being persisted while online...
It needs to deal with access_model
and many more things...
https://xmpp.org/extensions/xep-0060.html#accessmodels
Do you think of a better idea?
Thanks for the great work ;)
UI of User A should display that he has one unread message from User B
A user reported a bug regarding the interoperability of ngx-chat with Openfire 4.4.2
might be related with #15
Hey,
i have an Issue with uploading files to my openfire. I use the HTTPFileUploadPlugin, Openfire Http File Upload Plugin and <input type"file> from angular. I actually receive the correct object (imo):
File {name: "example.txt", lastModified: 1602250514537, lastModifiedDate: Fri Oct 09 2020 15:35:14 GMT+0200 (Mitteleuropäische Sommerzeit), webkitRelativePath: "", size: 241, …}
i pass that on to httpfileuploadplugin.upload(file), and i receive this http error:
HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: "http://localhost:7443/httpfileupload/1057a382-ca35-49d1-bb90-ef76b1617730/example.txt", ok: false, …}
aswell as:
PUT http://localhost:7443/httpfileupload/1057a382-ca35-49d1-bb90-ef76b1617730/example.txt net::ERR_INVALID_HTTP_RESPONSE
When i check my openfire logs i get the following messages (which indicate it working imo):
2021.01.14 15:11:37 INFO [pool-37-thread-6]: nl.goodbytes.xmpp.xep0363.Component - Entity 'alice@localhost/9aie25a97n' tries to obtain slot. 2021.01.14 15:11:37 INFO [pool-37-thread-6]: nl.goodbytes.xmpp.xep0363.Component - Entity 'alice@localhost/9aie25a97n' obtained slot for 'example.txt' (241 bytes). PUT-URL: http://localhost:7443/httpfileupload/1057a382-ca35-49d1-bb90-ef76b1617730/example.txt GET-URL: http://localhost:7443/httpfileupload/1057a382-ca35-49d1-bb90-ef76b1617730/example.txt
Any advice on why these erros occur?
Best regards
DevRichter
Hello,
i have a Problem where after i send a Message to a Groupchat, it creates a new Contact with the JID of the room in my Contacts (for example [email protected]). I cant find a call for the method addContact() or getOrCreateContactById(). Any Ideas how that might happen?
Also now that i have these rooms as actual contacts, i want to remove them from my contacts. But i get the following error:
ChatService: unknown stanza <= <iq xmlns="jabber:client" type="error" id="692-226" from="[email protected]" to="[email protected]/505al42tos"><query xmlns="jabber:iq:roster"><item jid="[email protected]" subscription="remove"/></query><error code="400" type="modify"><bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/><text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">IQ request cannot be processed by the MUC room itself.</text></error></iq>
This error persists for existing rooms, when trying to removeContact().
ChatService: unknown stanza <= <presence xmlns="jabber:client" type="error" from="[email protected]" to="[email protected]/505al42tos"><error code="400" type="modify"><jid-malformed xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/><text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">A nickname (resource-part) is required in order to join a room.</text></error></presence>
This error persists for deleted rooms, when trying to removeContact().
Using the deleteRoom() method yields the deletion of the room, but not of the removal of the groupchat within my contacts, any suggestions?
Hi Trampi!
I had some problems with retrieving MUC messages from archive, but it was wrong configuration of my ejabberd server (history: 0).
I changed configuration, deleted and created new database, restarted server and.... voila! Everything is working great! :))))
I have spend over two days trying to establish if loading from archive is implemented or find any errors (because maybe XMPP specifications was changed) in your code, but as usual, there are no errors in your rock solid code, there is my inexperience only.
Openfire has REST API feature that allows adding additional properties to user entry.
I'm guessing this feature is specific for Openfire only but are there any ways to retrieve this information in Contact metadata?
Error:
Cannot read property 'messages$' of undefined
at ChatMessageListComponent.ngOnInit (pazznetwork-ngx-chat.js:3788)
From app.component.html
:
<ng-template #messagesComponentInformation>You need to be logged in and have contacts to see this component</ng-template>
Description clearly states "You need to be logged in and have contacts to see this component".
But there is no check in the code if there are contacts
.
And then in ChatMessageListComponent
program is trying to subscribe to undefined variable
this.messageSubscription = this.contact.messages$.subscribe(()...
which throws error.
My solution:
<ng-container *ngIf="(this.chatService.state$.getValue() === 'online') && ((this.chatService.contactsSubscribed$ | async).length > 0); else messagesComponentInformation">
I can not connect to openfire server, any special configuration for this server?
Hi - I installed via:
npm install --save @pazznetwork/ngx-chat @xmpp/client@~0.9.2
and see these errors with ng build:
ERROR in node_modules/@pazznetwork/ngx-chat/lib/components/chat.component.d.ts(28,9): error TS1086: An accessor cannot be declared in an ambient context.
node_modules/@pazznetwork/ngx-chat/lib/core/contact.d.ts(27,9): error TS1086: An accessor cannot be declared in an ambient context.
node_modules/@pazznetwork/ngx-chat/lib/core/contact.d.ts(28,9): error TS1086: An accessor cannot be declared in an ambient context.
node_modules/@pazznetwork/ngx-chat/lib/core/contact.d.ts(29,9): error TS1086: An accessor cannot be declared in an ambient context.
node_modules/@pazznetwork/ngx-chat/lib/core/contact.d.ts(30,9): error TS1086: An accessor cannot be declared in an ambient context.
node_modules/@pazznetwork/ngx-chat/lib/core/contact.d.ts(31,9): error TS1086: An accessor cannot be declared in an ambient context.
node_modules/@pazznetwork/ngx-chat/lib/core/contact.d.ts(32,9): error TS1086: An accessor cannot be declared in an ambient context.
node_modules/@pazznetwork/ngx-chat/lib/services/adapters/xmpp/plugins/multi-user-chat.plugin.d.ts(35,9): error TS1086: An accessor cannot be declared in an ambient context.
node_modules/@pazznetwork/ngx-chat/lib/services/adapters/xmpp/plugins/multi-user-chat.plugin.d.ts(36,9): error TS1086: An accessor cannot be declared in an ambient context.
node_modules/@pazznetwork/ngx-chat/lib/services/adapters/xmpp/plugins/multi-user-chat.plugin.d.ts(37,9): error TS1086: An accessor cannot be declared in an ambient context.
When I try to use ngx-chat, I use the following per instructions:
@NgModule({
...
imports: [
...
NgxChatModule.forRoot(),
BrowserAnimationsModule, // alternatively NoopAnimationsModule
],
...
})
Then it requires an import. I have guessed it to be import { NgxChatModule } from @pazznetwork/ngx-chat
After adding these lines my pages won't display at all.
Hiow we can delete a message in this xmpp server by using pazznetwork ngx-chat
Hello, I tried to get ngx-chat to work using Ionic 5 & Angular 8 but after importing like described in the README I get following error:
Uncaught ReferenceError: global is not defined (index.js:43) at Object../node_modules/buffer/index.js (index.js:43) at __webpack_require__ (bootstrap:84) at Object../node_modules/safe-buffer/index.js (index.js:2) at __webpack_require__ (bootstrap:84) at Object../node_modules/hash-base/index.js (index.js:2) at __webpack_require__ (bootstrap:84) at Object../node_modules/md5.js/index.js (index.js:3) at __webpack_require__ (bootstrap:84) at Object../node_modules/create-hash/browser.js (browser.js:3) at __webpack_require__ (bootstrap:84)
I am working on a mobile app, which is why I use Ionic. Can someone help me resolve this issue?
Angular CLI; 9.0.2
Node: 10.16.3
OS: Windows x64 (Deploying on Android)
Angular: ~8.1.2
Ionic Angular: ^4.11.10
HI i am getting thios kind of issues while I am integrating with my application..suggest me solution
both do more or less the same. ChatMessageListComponent does support things like lazy loading of older messages and correct scroll behavior.
Hi Trampi!
Is it possible to view in real time list of all users which have joined selected room? And see their status.
In a way similar to Roster for Contacts: on the right side of screen, in a window which we can show/hide?
A user reported a bug regarding the interoperability of ngx-chat with prosody.
Might be related with #15
In the getting started part you say to add the constructor code:
constructor(@Inject(ChatServiceToken) ChatService) { chatService.logIn({ domain: 'ngx-chat.example', service: 'wss://ngx-chat.example:5280/websocket', password: 'password', username: 'someuser', }); }
but that gives a TS error : Cannot find name 'chatService'. Did you mean 'ChatService'?ts(2552)
FYI
When connecting with ejabberd 18.12.1-2~bpo9+1 on magicbroccoli.de, the connection errors and hangs. Might be caused by an "empty" account without messages / contacts.
ERROR TypeError: Cannot read property 'messages$' of undefined
at ChatMessageListComponent.ngOnInit (chat-message-list.component.ts:34)
at checkAndUpdateDirectiveInline (core.js:24489)
at checkAndUpdateNodeInline (core.js:35151)
at checkAndUpdateNode (core.js:35090)
at debugCheckAndUpdateNode (core.js:36112)
at debugCheckDirectivesFn (core.js:36055)
at Object.eval [as updateDirectives] (AppComponent.html:77)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:36043)
at checkAndUpdateView (core.js:35055)
at callViewAction (core.js:35421)
View_AppComponent_2 @ AppComponent.html:77
logError @ core.js:36330
handleError @ core.js:7239
(anonymous) @ core.js:32080
invoke @ zone-evergreen.js:359
run @ zone-evergreen.js:124
runOutsideAngular @ core.js:30818
tick @ core.js:32077
(anonymous) @ core.js:31915
invoke @ zone-evergreen.js:359
onInvoke @ core.js:30892
invoke @ zone-evergreen.js:358
run @ zone-evergreen.js:124
run @ core.js:30757
next @ core.js:31912
schedulerFn @ core.js:27834
__tryOrUnsub @ Subscriber.js:183
next @ Subscriber.js:122
_next @ Subscriber.js:72
next @ Subscriber.js:49
next @ Subject.js:39
emit @ core.js:27796
checkStable @ core.js:30835
onHasTask @ core.js:30912
hasTask @ zone-evergreen.js:411
_updateTaskCount @ zone-evergreen.js:431
_updateTaskCount @ zone-evergreen.js:264
runTask @ zone-evergreen.js:185
drainMicroTaskQueue @ zone-evergreen.js:559
invokeTask @ zone-evergreen.js:469
invokeTask @ zone-evergreen.js:1603
globalZoneAwareCallback @ zone-evergreen.js:1629
Show 20 more frames
16:34:06.329
ERROR TypeError: Cannot read property 'dateMessagesGroups' of undefined
at Object.eval [as updateDirectives] (ChatMessageListComponent.html:2)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:36043)
at checkAndUpdateView (core.js:35055)
at callViewAction (core.js:35421)
at execComponentViewsAction (core.js:35349)
at checkAndUpdateView (core.js:35062)
at callViewAction (core.js:35421)
at execEmbeddedViewsAction (core.js:35378)
at checkAndUpdateView (core.js:35056)
at callViewAction (core.js:35421)
View_ChatMessageListComponent_0 @ ChatMessageListComponent.html:2
proxyClass @ compiler.js:19199
logError @ core.js:36330
handleError @ core.js:7239
(anonymous) @ core.js:32080
invoke @ zone-evergreen.js:359
run @ zone-evergreen.js:124
runOutsideAngular @ core.js:30818
tick @ core.js:32077
(anonymous) @ core.js:31915
invoke @ zone-evergreen.js:359
onInvoke @ core.js:30892
invoke @ zone-evergreen.js:358
run @ zone-evergreen.js:124
run @ core.js:30757
next @ core.js:31912
schedulerFn @ core.js:27834
__tryOrUnsub @ Subscriber.js:183
next @ Subscriber.js:122
_next @ Subscriber.js:72
next @ Subscriber.js:49
next @ Subject.js:39
emit @ core.js:27796
checkStable @ core.js:30835
onLeave @ core.js:30953
onInvoke @ core.js:30895
invoke @ zone-evergreen.js:358
run @ zone-evergreen.js:124
run @ core.js:30757
(anonymous) @ xmpp-chat-connection.service.ts:63
emit @ events.js:146
EventEmitter.<computed> @ EventEmitter.js:46
listeners.element @ index.js:118
emit @ events.js:146
onEndElement @ FramedParser.js:14
(anonymous) @ Parser.js:33
emit @ events.js:146
SaxLtx._handleTagOpening @ ltx.js:38
SaxLtx.write @ ltx.js:127
write @ Parser.js:67
listeners.data @ index.js:68
emit @ events.js:146
listeners.message @ Socket.js:27
invokeTask @ zone-evergreen.js:391
runTask @ zone-evergreen.js:168
invokeTask @ zone-evergreen.js:465
invokeTask @ zone-evergreen.js:1603
globalZoneAwareCallback @ zone-evergreen.js:1629
Show 38 more frames
16:34:06.344
xmpp domain: magicbroccoli.de
host websocket endpoint: wss://magicbroccoli.de/xmpp-websocket
Hey,
i have a question regarding how to write tests using this repository. I have to use the Jasmine/Karma testing framework from Angular. I am not very well versed in writing tests, but as far as i understand you normally would mock incoming data, and tests the functions with the mocked data. In that way you would need to mock the objects with all of their attributes, for it to work. Using this repository though, the datastructers have very many attributes, and mocking those seems like a daunting task, for someone inexpirienced. Is there any advise for testing?
Best regards
DevRichter
Hi guys. I try to send and receive messages and I do not get it. Please, an example. Lola ;)
at the moment, dependencies between plugins are not explicit and make testing harder. getPlugin
-calls should be replaced with constructor injection where possible.
Hi! I`m using Angular 11 and have these errors
Error: node_modules/@pazznetwork/ngx-chat/lib/core/stanza.d.ts:9:18 - error TS2430: Interface 'IqResponseStanza' incorrectly extends interface 'Stanza'.
Types of property 'attrs' are incompatible.
Type '{ id: string; type: "error" | "result"; from?: string | undefined; to?: string | undefined; }' is not assignable to type '{ [key: string]: string; }'.
Property 'from' is incompatible with index signature.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
9 export interface IqResponseStanza extends Stanza {
~~~~~~~~~~~~~~~~
node_modules/@pazznetwork/ngx-chat/lib/core/stanza.d.ts:17:18 - error TS2430: Interface 'PresenceStanza' incorrectly extends interface 'Stanza'.
Types of property 'attrs' are incompatible.
Type '{ from?: string | undefined; to?: string | undefined; type?: string | undefined; }' is not assignable to type '{ [key: string]: string; }'.
Property 'from' is incompatible with index signature.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
17 export interface PresenceStanza extends Stanza {
~~~~~~~~~~~~~~
node_modules/@pazznetwork/ngx-chat/lib/core/stanza.d.ts:24:18 - error TS2430: Interface 'MessageWithBodyStanza' incorrectly extends interface 'Stanza'.
Types of property 'attrs' are incompatible.
Type '{ to?: string | undefined; from?: string | undefined; type?: string | undefined; id?: string | undefined; }' is not assignable to type '{ [key: string]: string; }'.
Property 'to' is incompatible with index signature.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.
24 export interface MessageWithBodyStanza extends Stanza {
it`s my dependencies
"dependencies": {
"@angular/animations": "~11.0.3",
"@angular/cdk": "^10.0.2",
"@angular/common": "~11.0.3",
"@angular/compiler": "~11.0.3",
"@angular/core": "~11.0.3",
"@angular/forms": "~11.0.3",
"@angular/platform-browser": "~11.0.3",
"@angular/platform-browser-dynamic": "~11.0.3",
"@angular/router": "~11.0.3",
"@ng-select/ng-select": "^5.1.0",
"@ngneat/hot-toast": "^1.0.11",
"@ngneat/overview": "^1.0.0",
"@ngneat/until-destroy": "^8.0.3",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
"@pazznetwork/ngx-chat": "^0.10.6",
"@xmpp/client": "^0.9.2",
"bootstrap": "^4.6.0",
"ngx-bootstrap": "^6.2.0",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1100.3",
"@angular/cli": "~11.0.3",
"@angular/compiler-cli": "~11.0.3",
"@biesbjerg/ngx-translate-extract": "^7.0.3",
"@types/jasmine": "~3.6.0",
"@types/ltx": "^2.8.1",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.1",
"husky": "^4.3.8",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~5.1.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"protractor": "~7.0.0",
"rxjs-tslint-rules": "^4.34.7",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"tslint-eslint-rules": "^5.4.0",
"tslint-microsoft-contrib": "^6.2.0",
"typescript": "~4.0.2"
}
Hello Trumpi!
Your app won't compile if you enable ivy by adding enableIvy": true
to "angularCompilerOptions" in tsconfig.json
file ( https://angular.io/guide/ivy ).
I don't know if is possible to have ivy enabled and still using your app, so please take a look at this problem, if you find free moment.
With ivy enabled there are many, many build errors, like this:
BUILD ERROR
node_modules/@angular/common/common.d.ts(115,22): error TS-996002: Appears in the NgModule.imports of NgxChatModule, but could not be resolved to an NgModule class
node_modules/@angular/forms/forms.d.ts(2669,22): error TS-996002: Appears in the NgModule.imports of NgxChatModule, but could not be resolved to an NgModule class
node_modules/@angular/common/http/http.d.ts(2799,22): error TS-996002: Appears in the NgModule.imports of NgxChatModule, but could not be resolved to an NgModule class
node_modules/@angular/cdk/text-field/typings/text-field-module.d.ts(8,22): error TS-996002: Appears in the NgModule.imports of NgxChatModule, but could not be resolved to an NgModule class
projects/pazznetwork/ngx-chat/src/lib/components/chat-room-messages/chat-room-messages.component.ts(15,14): error TS-993001: Unsupported private class ChatRoomMessagesComponent. This class is visible to consumers via NgxChatModule -> ChatRoomMessagesComponent, but is not exported from the top-level library entrypoint.
projects/pazznetwork/ngx-chat/src/lib/components/chat-filedrop/file-drop.component.ts(8,14): error TS-993001: Unsupported private class FileDropComponent. This class is visible to consumers via NgxChatModule -> FileDropComponent, but is not exported from the top-level library entrypoint.
projects/pazznetwork/ngx-chat/src/lib/directives/links.directive.ts(9,14): error TS-993001: Unsupported private class LinksDirective. This class is visible to consumers via NgxChatModule -> LinksDirective, but is not exported from the top-level library entrypoint.
node_modules/@angular/common/common.d.ts(115,22): error TS-996002: Appears in the NgModule.imports of NgxChatModule, but could not be resolved to an NgModule class
node_modules/@angular/forms/forms.d.ts(2669,22): error TS-996002: Appears in the NgModule.imports of NgxChatModule, but could not be resolved to an NgModule class
node_modules/@angular/common/http/http.d.ts(2799,22): error TS-996002: Appears in the NgModule.imports of NgxChatModule, but could not be resolved to an NgModule class
node_modules/@angular/cdk/text-field/typings/text-field-module.d.ts(8,22): error TS-996002: Appears in the NgModule.imports of NgxChatModule, but could not be resolved to an NgModule class
projects/pazznetwork/ngx-chat/src/lib/components/chat-room-messages/chat-room-messages.component.ts(15,14): error TS-993001: Unsupported private class ChatRoomMessagesComponent. This class is visible to consumers via NgxChatModule -> ChatRoomMessagesComponent, but is not exported from the top-level library entrypoint.
projects/pazznetwork/ngx-chat/src/lib/components/chat-filedrop/file-drop.component.ts(8,14): error TS-993001: Unsupported private class FileDropComponent. This class is visible to consumers via NgxChatModule -> FileDropComponent, but is not exported from the top-level library entrypoint.
projects/pazznetwork/ngx-chat/src/lib/directives/links.directive.ts(9,14): error TS-993001: Unsupported private class LinksDirective. This class is visible to consumers via NgxChatModule -> LinksDirective, but is not exported from the top-level library entrypoint.
Error: node_modules/@angular/common/common.d.ts(115,22): error TS-996002: Appears in the NgModule.imports of NgxChatModule, but could not be resolved to an NgModule class
node_modules/@angular/forms/forms.d.ts(2669,22): error TS-996002: Appears in the NgModule.imports of NgxChatModule, but could not be resolved to an NgModule class
node_modules/@angular/common/http/http.d.ts(2799,22): error TS-996002: Appears in the NgModule.imports of NgxChatModule, but could not be resolved to an NgModule class
node_modules/@angular/cdk/text-field/typings/text-field-module.d.ts(8,22): error TS-996002: Appears in the NgModule.imports of NgxChatModule, but could not be resolved to an NgModule class
projects/pazznetwork/ngx-chat/src/lib/components/chat-room-messages/chat-room-messages.component.ts(15,14): error TS-993001: Unsupported private class ChatRoomMessagesComponent. This class is visible to consumers via NgxChatModule -> ChatRoomMessagesComponent, but is not exported from the top-level library entrypoint.
projects/pazznetwork/ngx-chat/src/lib/components/chat-filedrop/file-drop.component.ts(8,14): error TS-993001: Unsupported private class FileDropComponent. This class is visible to consumers via NgxChatModule -> FileDropComponent, but is not exported from the top-level library entrypoint.
projects/pazznetwork/ngx-chat/src/lib/directives/links.directive.ts(9,14): error TS-993001: Unsupported private class LinksDirective. This class is visible to consumers via NgxChatModule -> LinksDirective, but is not exported from the top-level library entrypoint.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.