I am going to post all my methods inside my app just to keep this clear for me to read. Here is the goal. When a user enters a room, a message is added "USER HAS ENTERED THE ROOM" - that works fine. Now, what I want to do is when a user LEAVES a room, I want it to say "USER HAS LEFT THE ROOM" - the notification works, but it is showing the wrong username (it shows the username of the person SEEING the message.
What is it I a missing or not grasping
methods: {
connect() {
if (this.currentRoom?.id) {
let vm = this;
this.getMessages();
Echo.join("chat." + this.currentRoom.id)
.here(users => {
this.sendUserActivityNotification(this.$page.props.user, true)
this.users = users
this.usersCount = users.length
})
.joining(user => {
this.users.push(user)
this.usersCount = this.usersCount+1
})
.leaving(user => {
this.sendUserActivityNotification(this.$page.props.user, false)
this.users = this.users.filter(({id}) => (id !== user.id))
this.usersCount = this.usersCount-1
})
.listen('NewChatMessage', (e) => {
vm.getMessages();
});
}
},
setRoom(room) {
this.currentRoom = room;
},
getMessages() {
axios.get('/chat/room/' + this.currentRoom.id + '/messages')
.then(response => {
this.messages = response.data;
})
.catch(error => {
console.log(error);
})
},
sendUserActivityNotification(user, joining) {
const message = `${user.name} has ${joining === true ? 'entered' : 'left'} the room.`
return axios.post(`/chat/room/${this.currentRoom.id}/notifications`, {message}).then(() => this.getMessages())
.catch(console.error)
},
leaveRoom({id}) {
this.$store.dispatch(RoomTypes.LEAVE_ROOM, id)
}
},
I haven't used Laravel Echo, but after reading your code I think on the leaving method call, you are passing current user instead of what you are receiving from the event when you call the sendUserActivityNotification method.
Your implementation looks like this:
...
.leaving(user => {
this.sendUserActivityNotification(this.$page.props.user, false)
this.users = this.users.filter(({id}) => (id !== user.id))
this.usersCount = this.usersCount-1
})
....
You are passing this.$page.props.user to this.sendUserActivityNotification method instead of passing user.
You must change that call to this.sendUserActivityNotification(user, false)
Related
In order to implement in app purchase using expo am using https://docs.expo.io/versions/latest/sdk/in-app-purchases.
I implemented as per the document and i tested it in sandbox mode.what i have did is:
1)Set up in app purchase in appstore.
2)implement the functionality accordingly.
3)Validate receipt with cloud function and return the expiry date.
My question here is is there anything to do in our end regarding the billing?in sandbox mode if it is a fake transaction it didn't ask anything about payment.How it work in production is it differently and need we do anything for managing billing?
Any explanation, suggestions and corrections will be awesome.
My code is:
........
if (InAppPurchases.setPurchaseListener) {
InAppPurchases.setPurchaseListener(({ responseCode, results, errorCode }) => {
if (responseCode === InAppPurchases.IAPResponseCode.OK) {
results.forEach(purchase => {
if (!purchase.acknowledged) {
if (purchase.transactionReceipt) {
if (Platform.OS === "ios") {
if (!this.flag) {
this.flag = true;
fetch("url", {
method: "POST",
body: JSON.stringify(purchase),
headers: { "Content-type": "application/json;charset=UTF-8" }
})
.then(response => {
if (response.ok) {
return response.json();
}
})
.then(json => {
if (json && Object.keys(json).length) {
let subscriptionDetails = {};
subscriptionDetails.subscribed = json.isExpired;
subscriptionDetails.expiry = JSON.parse(json.expiryDate);
subscriptionDetails.inTrialPeriod = json.inTrial;
subscriptionDetails.productId = json.id;
SecureStore.setItemAsync(
"Subscription",
JSON.stringify(subscriptionDetails)
)
.then(() => {
console.info("subscription Saved:");
store.dispatch(
setWsData("isSubscriptionExpired", json.isExpired)
);
let expired = json.isExpired;
store.dispatch(setUiData("isCheckAnalyze", true));
store.dispatch(setWsData("firstSubscription", false));
this.setState({ checkExpiry: json.isExpired });
if (!expired) {
InAppPurchases.finishTransactionAsync(purchase, true);
alert("Now you are Subscribed!!");
} else {
alert("Expired");
}
})
.catch(error =>
console.error("Cannot save subscription details:", error)
);
}
})
.catch(err => console.log("error:", err));
}
}
}
}
});
We are using .pipe(takeUntil) in the logincomponent.ts. What I need is, it should get destroyed after successful log in and the user is on the landing page. However, the below snippet is being called even when the user is trying to do other activity and hitting submit on the landing page should load different page but the result of submit button is being overridden and taken back to the landing page.
enter code hereforkJoin({
flag: this.auth
.getEnvironmentSettings('featureEnableQubeScan')
.pipe(take(1)),
prefs: this.auth.preferences.pipe(take(1)),
}).subscribe(
(result: any) => {
this.qubeScanEnabled = result.flag.featureEnableQubeScan;
this.userPrefs = result.prefs;
// check to see if we're authed (but don't keep listening)
this.auth.authed
.pipe(takeUntilComponentDestroyed(this))
.subscribe((payload: IJwtPayload) => {
if (payload) {
this.auth.accountO
.pipe(takeUntilComponentDestroyed(this))
.subscribe((account: IAccount) => {
if (this.returnUrl) {
this.router.navigateByUrl(this.returnUrl);
} else {
this.router.navigate(['dashboard']);
}
}
}
}
}
);
ngOnDestroy() {}
Custom Code:
export function takeUntilComponentDestroyed(component: OnDestroy) {
const componentDestroyed = (comp: OnDestroy) => {
const oldNgOnDestroy = comp.ngOnDestroy;
const destroyed$ = new ReplaySubject<void>(1);
comp.ngOnDestroy = () => {
oldNgOnDestroy.apply(comp);
destroyed$.next(undefined);
destroyed$.complete();
};
return destroyed$;
};
return pipe(
takeUntil(componentDestroyed(component))
);
}
Please let me know what I am doing wrong.
Versions:
rxjs: 6.5.5
Angular:10.0.8
Thanks
I've done a first pass at creating a stream that doesn't nest subscriptions and continues to have the same semantics. The major difference is that I can move takeUntilComponentDestroyed to the end of the stream and lets the unsubscibes filter backup the chain. (It's a bit cleaner and you don't run the same code twice every time through)
It's a matter of taste, but flattening operators are a bit easier to follow for many.
enter code hereforkJoin({
flag: this.auth
.getEnvironmentSettings('featureEnableQubeScan')
.pipe(take(1)),
prefs: this.auth.preferences.pipe(take(1)),
}).pipe(
tap((result: any) => {
this.qubeScanEnabled = result.flag.featureEnableQubeScan;
this.userPrefs = result.prefs;
}),
mergeMap((result: any) => this.auth.authed),
filter((payload: IJwtPayload) => payload != null),
mergeMap((payload: IJwtPayload) => this.auth.accountO),
takeUntilComponentDestroyed(this)
).subscribe((account: IAccount) => {
if (this.returnUrl) {
this.router.navigateByUrl(this.returnUrl);
} else {
this.router.navigate(['dashboard']);
}
});
This function doesn't create another inner stream (destroyed$). This way is a bit more back to the basics so it should be easier to debug if you're not getting the result you want.
export function takeUntilComponentDestroyed<T>(comp: OnDestroy): MonoTypeOperatorFunction<T> {
return input$ => new Observable(observer => {
const sub = input$.subscribe({
next: val => observer.next(val),
complete: () => observer.complete(),
error: err => observer.error(err)
});
const oldNgOnDestroy = comp.ngOnDestroy;
comp.ngOnDestroy = () => {
oldNgOnDestroy.apply(comp);
sub.unsubscribe();
observer.complete();
};
return { unsubscribe: () => sub.unsubscribe() };
});
}
I am trying to build A CONVERSATIONAL BOT. when I am trying to pass the response with next , its not getting reflected din the next functions .
bot.dialog('Barcode',
(session, args, next) => {
var intent = args.intent;
var id = builder.EntityRecognizer.findEntity(intent.entities, 'Report.Id');
if (id) {
next({ response: id.entity });
} else {
builder.Prompts.text(session, 'Please enter your id');
}
session.endDialog();
} ,
(session,results) => {
var id = results.response;
session.send(id.toString()); -- i want the value to be passed here
}
).triggerAction({
matches: 'Barcode'
})
If you want to implement a workflow in a dialog, you can set IDialogWaterfallStep|IDialogWaterfallStep[] in the second parameter in dialog() function.
In your code, you forget to cover [] outside the steps.
Try:
bot.dialog('Barcode',[
(session, args, next) => {
var intent = args.intent;
var id = builder.EntityRecognizer.findEntity(intent.entities, 'Report.Id');
if (id) {
next({ response: id.entity });
} else {
builder.Prompts.text(session, 'Please enter your id');
}
session.endDialog();
} ,
(session,results) => {
var id = results.response;
session.send(id.toString()); -- i want the value to be passed here
}]
).triggerAction({
matches: 'Barcode'
})
I have a join to a private channel:
Echo.private('chat_room.'+comments_room_id)
.listen('.App.Events.Common.Comment.CommentCreated', function(e) {
e.comment.user = e.user;
e.comment.new_msg = 1;
_this.comment_room.comments.unshift(e.comment);
});
I would like to use the .here() presence call to keep a array of users updated with who is currently online.
I tried the following:
Echo.private('chat_room.'+comments_room_id)
.here(users => {
this.users = users;
})
.listen('.App.Events.Common.Comment.CommentCreated', function(e) {
But that did not work...
Error in console is:
Echo.private(...).here is not a function
So i discovered that you need to also join a Presence channel alongside the private channel in order to use the here() methods.
Echo.join('chat_room.'+comments_room_id)
.here((users) => {
this.users = users;
})
.joining((user) => {
this.users.push(user)
})
.leaving((person) => {
this.users = _.reject(this.users, user => user.id == person.id);
});
I am using the this great angular2-modal but can't figure out how to return a result value from my custom modal.
I instantiate it like this:
let dialog: Promise<ModalDialogInstance>;
let bindings = Injector.resolve([
provide(ICustomModal, { useValue: this.gewaehltesBild })
]);
var self = this;
dialog = this.modal.open(
<any>ImagecropperComponent,
bindings,
new ModalConfig("md", true, 27));
dialog.then((resultPromise) => {
return resultPromise.result.then((result) => {
this.lastModalResult = result;
this.mitarbeiter.avatarImg = this.gewaehltesBild;
$(self.elementRef.nativeElement).find('#bildSelector').val("");
}, () => this.lastModalResult = 'Rejected!');
});
I have tried to send my returnvalue with
this.dialog.close(this.croppedImage);
but result is always null. Is there a convention in angular2 how to return values from components, that is used by angular2-modal?
Thank you!
Works fine for me, I too am using custom dialog and here is how i catch the result
var dialog = this._modal.open(VideoPlayerComponent,
resolvedBindings,
new ModalConfig('lg', true, 27));
dialog
.then((d) => d.result)
.then((r) => { console.log(r); }, (error) => { console.log(r); });
When i call close on the instance
this._dialog.close("Hello");
It does print Hello