I am trying to implement this plugin Phonegap system notification. I am reading two Rss feeds and displaying it to the user as a Status bar notification. Once the Notifications has been displayed to the user and the user clicks on the notification, he is taken to the app but I am not able to clear the notifications from the status bar. Could you please suggest me a way to clear these notifications by looking at my code.
How can I call navigator.systemNotification.cancelNotification() when the user clicks on the statusbar notification.
notification.js
google.load("feeds", "1");
google.setOnLoadCallback(function () {
var rss1old = '',
rss1new = '',
rss2old ='',
rss2new ='',
getRss = function (url, callback) {
(url) && (function (url) {
var feed = new google.feeds.Feed(url);
feed.load(function (result) {
(!result.error && callback) && (callback(result.feed.entries[0].title));
});
}(url));
};
setInterval(function () {
getRss(
'http://yofreesamples.com/category/free-coupons/feed/?type=rss',
function (title) {
rss1new = title;
if(rss1old !== rss1new) {
rss1old = rss1new;
navigator.systemNotification.onBackground();
navigator.systemNotification.updateNotification(rss1new,1);
navigator.notification.beep(1);
navigator.notification.vibrate(2000);
}
}
);
}, 5000);
setInterval(function () {
getRss(
'http://yofreesamples.com/category/real-freebies/feed/?type=rss',
function (title) {
rss2new = title;
if(rss2old !== rss2new) {
rss2old = rss2new;
navigator.systemNotification.onBackground();
navigator.systemNotification.updateNotification(rss2new,1);
navigator.notification.beep(1);
navigator.notification.vibrate(1000);
}
}
);
}, 6000);
});
SystemNotification.js -> Included from the plugin
function SystemNotification() {
}
SystemNotification.prototype.notificationEnabled = false;
SystemNotification.prototype.newCount = 0; //to keep track of multiple notifications events
SystemNotification.prototype.enableNotification = function () {
this.notificationEnabled = true;
};
SystemNotification.prototype.disableNotification = function () {
this.notificationEnabled = false;
};
SystemNotification.prototype.onBackground = function () {
this.enableNotification();
};
SystemNotification.prototype.onForeground = function () {
this.disableNotification();
};
SystemNotification.prototype.createStatusBarNotification = function (contentTitle, contentText, tickerText) {
PhoneGap.exec(null, null, "systemNotification", "createStatusBarNotification", [contentTitle, contentText, tickerText]);
};
SystemNotification.prototype.updateNotification = function (contentText, tickerText, number) {
this.newCount++;
var contentTitle = this.newCount + "RssFeeds";
if (this.newCount === 1) {
this.createStatusBarNotification(contentTitle, contentText, tickerText);
} else {
PhoneGap.exec(null, null, "systemNotification", "updateNotification", [contentTitle, contentText, this.newCount]);
this.showTickerText(tickerText); //optional
}
};
SystemNotification.prototype.cancelNotification = function (contentText) {
this.newCount--;
if (this.newCount === 0) {
PhoneGap.exec(null, null, "systemNotification", "cancelNotification", []);
}
else {
//updating the notification
var contentTitle = "my title";
PhoneGap.exec(null, null, "systemNotification", "updateNotification", [contentTitle, contentText, this.newCount]);
}
};
SystemNotification.prototype.showTickerText = function (tickerText) {
PhoneGap.exec(null, null, "systemNotification", "showTickerText", [tickerText]);
};
SystemNotification.prototype.touch = function () {
PhoneGap.exec(null, null, "systemNotification", "touch", []);
};
PhoneGap.addConstructor(function () {
if (typeof(navigator.systemNotification) == "undefined") {
navigator.systemNotification = new SystemNotification();
navigator.systemNotification.touch(); //this ensures that the plugin is added when phonegap kicks off
}
});
Systemnotification.Java -> Included from the plugin
package com.yfs.project;
import org.json.JSONArray;
import org.json.JSONException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResult;
public class SystemNotification extends Plugin {
final int notif_ID = 1234;
NotificationManager notificationManager;
Notification note;
PendingIntent contentIntent;
#Override
public PluginResult execute(String action, JSONArray args, String callbackId)
{
PluginResult.Status status = PluginResult.Status.OK;
String result = "";
try {
if (action.equals("createStatusBarNotification")) {
this.createStatusBarNotification(args.getString(0), args.getString(1), args.getString(2));
}
else if (action.equals("updateNotification")) {
this.updateNotification(args.getString(0), args.getString(1), args.getInt(2));
}
else if (action.equals("cancelNotification")) {
this.cancelNotification();
}
else if (action.equals("showTickerText")) {
this.showTickerText(args.getString(0));
}
return new PluginResult(status, result);
} catch(JSONException e) {
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
}
private void updateNotification(String contentTitle, String contentText, int number)
{
note.setLatestEventInfo(this.ctx, contentTitle, contentText, contentIntent);
note.number = number;
notificationManager.notify(notif_ID,note);
}
private void createStatusBarNotification(String contentTitle, String contentText, String tickerText)
{
notificationManager = (NotificationManager) this.ctx.getSystemService(Context.NOTIFICATION_SERVICE);
note = new Notification(R.drawable.rss, tickerText, System.currentTimeMillis() );
//change the icon
Intent notificationIntent = new Intent(this.ctx, Yfs.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent = notificationIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
contentIntent = PendingIntent.getActivity(this.ctx, 0, notificationIntent, 0);
note.setLatestEventInfo(this.ctx, contentTitle, contentText, contentIntent);
note.number = 1; //Just created notification so number=1. Remove this line if you dont want numbers
notificationManager.notify(notif_ID,note);
}
private void cancelNotification()
{
notificationManager.cancel(notif_ID);
}
private void showTickerText(String tickerText)
{
note.tickerText = tickerText;
notificationManager.notify(notif_ID,note);
}
public void onPause()
{
super.webView.loadUrl("javascript:navigator.systemNotification.onBackground();");
}
public void onResume()
{
super.webView.loadUrl("javascript:navigator.systemNotification.onForeground();");
}
}
On android, you'll need to set the flag AUTO_CANCEL
Where you have this
note = new Notification(R.drawable.rss, tickerText, System.currentTimeMillis() );
Add this line right under
note.flags = Notification.FLAG_AUTO_CANCEL;
Related
I have the following webview implementation built by borrowing code (I am learning SwiftUI). I want to show a message in the webview when the networks is down. It works with a static html loaded from a string and a button but I am unable to do the same calling a web server and triggering javascript using the network status.
import SwiftUI
import WebKit
import Combine
private let urlString: String = "http://127.0.0.1"
class WebViewData: ObservableObject {
#Published var parsedText: NSAttributedString? = nil
var functionCaller = PassthroughSubject<Void,Never>()
var isInit = false
var shouldUpdateView = true
}
struct WebView: UIViewRepresentable {
#StateObject var data: WebViewData
func makeUIView(context: Context) -> WKWebView {
let wkWebview = WKWebView()
wkWebview.navigationDelegate = context.coordinator
return wkWebview
}
func updateUIView(_ uiView: WKWebView, context: Context) {
guard data.shouldUpdateView else {
data.shouldUpdateView = false
return
}
context.coordinator.tieFunctionCaller(data: data)
context.coordinator.webView = uiView
guard let url = URL(string: urlString) else { return }
let request = URLRequest(url: url)
uiView.load(request)
}
func makeCoordinator() -> WebViewCoordinator {
return WebViewCoordinator(view: self)
}
func viewWillAppear(_ uiView: WKWebView, context: UIViewRepresentableContext<WebView>){
}
}
class WebViewCoordinator : NSObject, WKNavigationDelegate {
var parent: WebView
var webView: WKWebView? = nil
private var cancellable : AnyCancellable?
init(view: WebView) {
self.parent = view
super.init()
}
func tieFunctionCaller(data: WebViewData) {
cancellable = data.functionCaller.sink(receiveValue: { _ in
self.webView?.evaluateJavaScript("message_generator(\"network_down\"")
})
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
DispatchQueue.main.async {
if !self.parent.data.isInit {
self.parent.data.isInit = true
}
}
}
}
Here the ContentView:
import SwiftUI
struct ContentView: View {
#StateObject var webViewData = WebViewData()
#ObservedObject var networkManager = NetworkManager()
var body: some View {
ZStack{
Color.white
VStack {
ExecuteCode {
print(networkManager.isConnected)
webViewData.functionCaller.send() //???
}
WebView(data: webViewData)
if (!networkManager.isConnected) {
//???
}
}
.onReceive(webViewData.$parsedText, perform: { parsedText in
if let parsedText = parsedText {
print(parsedText)
}
})
}
}
}
struct ExecuteCode : View {
init( _ codeToExec: () -> () ) {
codeToExec()
}
var body: some View {
return EmptyView()
}
}
Here the NetworkManager:
import Foundation
import Network
class NetworkManager: ObservableObject {
let monitor = NWPathMonitor()
let queue = DispatchQueue(label: "NetworkManager")
#Published var isConnected = true
var imageName: String {
return isConnected ? "wifi" : "wifi.slash"
}
var connectionDescription: String {
if isConnected {
return "Internet connection looks good!"
} else {
return "It looks like you're not connected to the internet. Make sure WiFi is enabled and try again"
}
}
init() {
monitor.pathUpdateHandler = { path in
DispatchQueue.main.async {
if path.status == .satisfied {
self.isConnected = true
} else {
self.isConnected = false
}
}
}
monitor.start(queue: queue)
}
}
Thanks for helping.
Pointers to good docs are very appreciated.
In this code I retrieve data about a country as an observable. I then try to compare my string this.city with this.capital which I retrieved from the Observable. If the two do not equal I want to display a new paragraph in the html by changing the hidden boolean to false. I know that this.city and the observable this.capital are not equal but it does not display the paragraph in the html after calling showHeader().
I wonder if you can compare Observable data with strings in this way?
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { SettingsPage } from '../../pages/settings/settings';
import { Storage } from '#ionic/storage';
import { CityDataProvider } from '../../providers/city-data/city-data';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
hidden: boolean = true;
hiddenTwo: boolean = true;
city: string;
cityData: any[];
capital: string;
cityLowerCase: string;
constructor(public navCtrl: NavController, private storage: Storage, private cdp: CityDataProvider) {
}
async ionViewWillEnter() {
const data = await this.storage.get("city")
.then((value) => {
if (value == null) { this.hidden = false; } else if (value !== null) { this.hidden = true; }
this.city = value;
})
.catch((error) => {
alert("Error accessing storage.")
})
this.cdp.getCityData(this.city).subscribe(data => {
this.cityData = data;
this.capital = data[0].capital.toString().toLowerCase();
this.cityLowerCase = this.city.toLowerCase();
this.showHeader(this.cityLowerCase, this.capital);
});
}
showHeader(a: string, b: string) {
if (a != b){
this.hiddenTwo = false;
}
}
openSettingsPage() {
this.navCtrl.push(SettingsPage);
};`enter code here`
}
As you are using then on this.storage.get("city"), this.city has not been set yet when you call this.cdp.getCityData(this.city). Just use await properly.
Also, some basic tips:
if(a == b){...} else if(a != b){...} is essentially just if(a == b){...}else{...}
if(condition){value = true}else{value = false} is essentially just value = condition
async ionViewWillEnter() {
try
{
this.city = await this.storage.get("city");
this.hidden = this.city == null;
}
catch (error)
{
alert("Error accessing storage.")
}
this.cdp.getCityData(this.city).subscribe(data =>
{
this.cityData = data;
this.capital = data[0].capital.toString().toLowerCase();
this.cityLowerCase = this.city.toLowerCase();
this.showHeader(this.cityLowerCase, this.capital);
});
}
showHeader(a: string, b: string) {
this.hiddenTwo = a != b;
}
I am new in the Aurelia community and it was given to me a task to make an entire upgrade of my current platform. (more info at the bottom).
Current problem:
Every time i redirect to the logout.js model a message is prompt
ERROR [app-router] TypeError: "this.view is null"
Questions:
How does a custom component "if-permission" can influence on non-view model?
Conlusions:
- I started to believe that any of the big files bellow are influencing the error at all! After commenting most of the code the error what still showing!
- Removed the noView() logic and added an empty logout.html! Guess what? Works like a charm! The logout will redirect to the login page.
This is my RouteConfig.js
{
route: 'logout',
viewPorts: {
main: {
moduleId: PLATFORM.moduleName('pages/logout/logout')
}
},
nav: false,
sidebar: false,
auth: false,
title: 'Logout',
name: 'logout',
}
This is my logout.js
import { noView } from 'aurelia-framework';
import authService from 'services/authService';
import uiService from 'services/uiService';
#noView()
export class LogoutPage {
activate() {
//THE ERROR PROMPTS EVEN WITH THE ABOVE LINES COMMENTED
uiService.impersonate(null, false);
authService.logout();
}
}
After searching a while i noticed that "this.view" is declared on this 2 files:
if-permission.js
import { inject, customAttribute, templateController, BoundViewFactory, ViewSlot } from 'aurelia-framework';
import userService from 'services/api/userService';
#customAttribute('if-permission')
#inject(BoundViewFactory, ViewSlot)
#templateController
export class IfPermission {
constructor(viewFactory, viewSlot) {
this.viewFactory = viewFactory;
this.viewSlot = viewSlot;
this.showing = false;
this.view = null;
this.bindingContext = null;
this.overrideContext = null;
}
/**
* Binds the if to the binding context and override context
* #param bindingContext The binding context
* #param overrideContext An override context for binding.
*/
bind(bindingContext, overrideContext) {
// Store parent bindingContext, so we can pass it down
this.bindingContext = bindingContext;
this.overrideContext = overrideContext;
this.valueChanged(this.value);
}
valueChanged(newValue) {
if (this.__queuedChanges) {
this.__queuedChanges.push(newValue);
return;
}
let maybePromise = this._runValueChanged(newValue);
if (maybePromise instanceof Promise) {
let queuedChanges = this.__queuedChanges = [];
let runQueuedChanges = () => {
if (!queuedChanges.length) {
this.__queuedChanges = undefined;
return;
}
let nextPromise = this._runValueChanged(queuedChanges.shift()) || Promise.resolve();
nextPromise.then(runQueuedChanges);
};
maybePromise.then(runQueuedChanges);
}
}
_runValueChanged(newValue) {
newValue = userService.hasPermission(newValue);
if (!newValue) {
let viewOrPromise;
if (this.view !== null && this.showing) {
viewOrPromise = this.viewSlot.remove(this.view);
if (viewOrPromise instanceof Promise) {
viewOrPromise.then(() => this.view.unbind());
} else {
this.view.unbind();
}
}
this.showing = false;
return viewOrPromise;
}
if (this.view === null) {
this.view = this.viewFactory.create();
}
if (!this.view.isBound) {
this.view.bind(this.bindingContext, this.overrideContext);
}
if (!this.showing) {
this.showing = true;
return this.viewSlot.add(this.view);
}
}
/**
* Unbinds the if
*/
unbind() {
if (this.view === null) {
return;
}
this.view.unbind();
if (!this.viewFactory.isCaching) {
return;
}
if (this.showing) {
this.showing = false;
this.viewSlot.remove(this.view, true, true);
}
this.view.returnToCache();
this.view = null;
}
}
if-user-role.js
import { inject, customAttribute, templateController, BoundViewFactory, ViewSlot } from 'aurelia-framework';
import userService from 'services/api/userService';
#customAttribute('if-user-role')
#inject(BoundViewFactory, ViewSlot)
#templateController
export class IfUserRole {
constructor(viewFactory, viewSlot) {
this.viewFactory = viewFactory;
this.viewSlot = viewSlot;
this.showing = false;
this.view = null;
this.bindingContext = null;
this.overrideContext = null;
}
/**
* Binds the if to the binding context and override context
* #param bindingContext The binding context
* #param overrideContext An override context for binding.
*/
bind(bindingContext, overrideContext) {
// Store parent bindingContext, so we can pass it down
this.bindingContext = bindingContext;
this.overrideContext = overrideContext;
this.valueChanged(this.value);
}
valueChanged(newValue) {
if (this.__queuedChanges) {
this.__queuedChanges.push(newValue);
return;
}
let maybePromise = this._runValueChanged(newValue);
if (maybePromise instanceof Promise) {
let queuedChanges = this.__queuedChanges = [];
let runQueuedChanges = () => {
if (!queuedChanges.length) {
this.__queuedChanges = undefined;
return;
}
let nextPromise = this._runValueChanged(queuedChanges.shift()) || Promise.resolve();
nextPromise.then(runQueuedChanges);
};
maybePromise.then(runQueuedChanges);
}
}
_runValueChanged(newValue) {
newValue = userService.hasRole(newValue);
if (!newValue) {
let viewOrPromise;
if (this.view !== null && this.showing) {
viewOrPromise = this.viewSlot.remove(this.view);
if (viewOrPromise instanceof Promise) {
viewOrPromise.then(() => this.view.unbind());
} else {
this.view.unbind();
}
}
this.showing = false;
return viewOrPromise;
}
if (this.view === null) {
this.view = this.viewFactory.create();
}
if (!this.view.isBound) {
this.view.bind(this.bindingContext, this.overrideContext);
}
if (!this.showing) {
this.showing = true;
return this.viewSlot.add(this.view);
}
}
/**
* Unbinds the if
*/
unbind() {
if (this.view === null) {
return;
}
this.view.unbind();
if (!this.viewFactory.isCaching) {
return;
}
if (this.showing) {
this.showing = false;
this.viewSlot.remove(this.view, true, true);
}
this.view.returnToCache();
this.view = null;
}
}
With this update i have integrated Aurelia-cli, updated aurelia-webpack and all the dependencies. Which made me switch some code like:
Add PLATFORM.moduleName() to all my platform
Add Require to all modules that were only getting components via < compose >
I am using https://github.com/HsuanXyz/ionic3-chat this link. all are working very well, but i can't send and receive emoji on chat conversation screen.I am not able to send and receive emoji icons, I receive ???? when i send any emoji icon. can see below image:
My .html code is here:
<ion-footer no-border [style.height]="showEmojiPicker ? '255px' : '55px'">
<div class="input-wrap">
<button ion-button clear icon-only item-right (click)="switchEmojiPicker()">
<ion-icon name="md-happy"></ion-icon>
</button>
<textarea class="textMsg" #chat_input
placeholder="Type a message"
[(ngModel)]="editorMsg"
(keyup.enter)="sendMsg()"
(focusin)="onFocus()">
</textarea>
<button ion-button clear icon-only item-right (click)="sendMsg()">
<ion-icon name="ios-send" ios="ios-send" md="md-send"></ion-icon>
</button>
</div>
<emoji-picker [(ngModel)]="editorMsg"></emoji-picker>
</ion-footer>
.ts file code:
import { Component, ElementRef, ViewChild } from '#angular/core';
import { IonicPage, NavController, NavParams, AlertController } from 'ionic-angular';
import { Events, Content } from 'ionic-angular';
// import { ChatService, ChatMessage, UserInfo } from "../../providers/chat-service";
import * as moment from 'moment';
import { ServiceProvider } from '../../providers/service/service';
import { Storage } from "#ionic/storage";
import { Loader } from "../../providers/loader/loader";
// import { EmojiPickerComponentModule } from "../../components/emoji- picker/emoji-picker.module";
#IonicPage()
#Component({
selector: 'page-conversationchat',
templateUrl: 'conversationchat.html',
})
export class ConversationchatPage {
// selectedImojiPickerIten: EmojiPickerItem;
#ViewChild(Content) content: Content;
#ViewChild('chat_input') messageInput: ElementRef;
msgList: any[] = [];
// user: UserInfo;
// toUser: UserInfo;
editorMsg = '';
showEmojiPicker = false;
userId : any;
sessionId: any;
conversationData: any;
receiverPic: any;
receiverName: any;
receiverId: any;
conversationId: any;
chatType: any;
messages: any;
// toggled: boolean = false;
// emojitext: string;
constructor(public navCtrl: NavController, public navParams:
NavParams, private loader: Loader, private alertCtrl:
AlertController, private events: Events, public serviceProvider:
ServiceProvider, private storage: Storage) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad ConversationchatPage');
}
ionViewWillEnter() {
this.storage.get("userData").then(userData => {
// console.log("user profile data" +JSON.stringify(userData));
this.userId = userData.data.User_Id;
this.sessionId = userData.data.Session_Id;
});
this.storage.get("conversationData").then(conversationData => {
// console.log("conversationData"
+JSON.stringify(conversationData));
if(conversationData.Receiver_ProfilePic == "") {
this.receiverPic = "assets/imgs/profileuser.png";
} else {
this.receiverPic = conversationData.Receiver_ProfilePic;
}
this.receiverName = conversationData.Receiver_Name;
this.receiverId = conversationData.Receiver_Id;
this.conversationId = conversationData.Converstion_Id;
});
this.storage.get("chatType").then(chatType => {
this.chatType = chatType;
});
this.getMsg();
}
goBack() {
this.navCtrl.pop();
}
ionViewWillLeave() {
// unsubscribe
this.events.unsubscribe('chat:received');
}
ionViewDidEnter() {
//get message list
this.getMsg();
// Subscribe to received new message events
this.events.subscribe('chat:received', msg => {
this.pushNewMsg(msg);
})
}
onFocus() {
this.showEmojiPicker = false;
this.content.resize();
this.scrollToBottom();
}
switchEmojiPicker() {
this.showEmojiPicker = !this.showEmojiPicker;
if (!this.showEmojiPicker) {
this.focus();
} else {
this.setTextareaScroll();
}
this.content.resize();
this.scrollToBottom();
}
getMsg() {
let getConversionMsgObj = {
"User_Id": this.userId,
"sessionId": this.sessionId,
"Chat_Message": this.editorMsg,
"Chat_Id": this.receiverId,
"Chat_Type": this.chatType
}
this.serviceProvider.chatHistoryApi(getConversionMsgObj).then((result) => {
// console.log("result Conversation chat history"
+JSON.stringify(result));
if(result["success"] == 1) {
// this.loader.hide();
this.msgList = result["data"].ChatHistory;
// console.log("this.msgList", this.msgList);
for(let msgUserImage of this.msgList){
// console.log("msgUserImage", msgUserImage);
if(msgUserImage.User_ProfilePic == "") {
msgUserImage.User_ProfilePic = "assets/imgs/profileuser.png";
}
if(msgUserImage.Chat_Time) {
// var now = moment();
msgUserImage.Chat_Time = moment.utc(msgUserImage.Chat_Time);
}
}
this.scrollToBottom();
} else if(result["success"] == 4) {
// this.loader.hide();
let alert = this.alertCtrl.create({
subTitle: result["message"],
buttons: [
{
text: 'OK',
handler: () => {
console.log('ok clicked');
this.navCtrl.push("SigninPage");
}
}
]
});
alert.present();
} else if(result["success"] == 0) {
// this.loader.hide();
} else {
}
}, (err) => {
// this.loader.hide();
console.log("err profile" +JSON.stringify(err));
// Error log
});
}
sendMsg() {
if (!this.editorMsg.trim()) return;
// Mock message
const id = Date.now().toString();
let chatMsg = {
"User_Id": this.userId,
"sessionId": this.sessionId,
"Chat_Message": this.editorMsg,
"Chat_Id": this.conversationId,
"Chat_Type": this.chatType
};
this.pushNewMsg(chatMsg);
this.editorMsg = '';
if (!this.showEmojiPicker) {
this.focus();
}
// console.log("chatMsg", chatMsg);
this.serviceProvider.sendMessageApi(chatMsg).then((result) => {
// console.log("result profile" +JSON.stringify(result));
if(result["success"] == 1) {
this.scrollToBottom();
this.getMsg();
// let index = this.getMsgIndexById(id);
// if (index !== -1) {
// this.msgList[index].status = 'success';
// }
} else if(result["success"] == 4) {
this.loader.hide();
let alert = this.alertCtrl.create({
subTitle: result["message"],
buttons: [
{
text: 'OK',
handler: () => {
console.log('ok clicked');
this.navCtrl.push("SigninPage");
}
}
]
});
alert.present();
} else {
}
}, (err) => {
// this.loader.hide();
console.log("err profile" +JSON.stringify(err));
// Error log
});
}
pushNewMsg(msg) {
// console.log("msg pushMsg", msg);
const userId = this.userId,
toUserId = this.receiverId;
// Verify user relationships
if (msg.User_Id === userId && msg.Chat_Id === toUserId) {
this.msgList.push(msg);
} else if (msg.Chat_Id === userId && msg.User_Id === toUserId) {
this.msgList.push(msg);
}
this.scrollToBottom();
}
getMsgIndexById(id: string) {
return this.msgList.findIndex(e => e.messageId === id)
}
scrollToBottom() {
setTimeout(() => {
if (this.content.scrollToBottom) {
this.content.scrollToBottom();
}
}, 400)
}
private focus() {
if (this.messageInput && this.messageInput.nativeElement) {
this.messageInput.nativeElement.focus();
}
}
private setTextareaScroll() {
const textarea =this.messageInput.nativeElement;
textarea.scrollTop = textarea.scrollHeight;
}
}
How to solve this issue, I need a solution as soon as possible.
Check this awesome plugin -
Emoji
I have created an npm package for Ionic 4 & Ionic 5. https://github.com/Pankaj-Sati/ionic4-emoji-picker.
Features:
Slider like interface (Like WhatsApp & any other chat app)
Modal Support. Open Emoji Picker in a modal
Easy styling
I'm trying to make my call to the server with BreezeJS but can't get it to work. It says tblMovie is not recognized. I can't find the problem :S
When I want to add a new movie it says so.
show.js
self.viewAddMovieModal = function () {
self.app.showModal(new self.addmovie()).then(function (result) {
if (result != undefined) {
var movie = dataservice.createMovie({
Title: result[0].title,
Director: result[0].director
});
if (movie.entityAspect.validateEntity()) {
self.movies.push(new movie(result[0].title, result[0].director));
dataservice.saveChanges();
} else {
alert("Error");
}
}
});
};
My dataservice.js layer
/// <reference path="../../Scripts/breeze.debug.js"/>
define(["require"], function (require) {
var Dataservice = (function () {
function Dataservice(service) {
this.serviceName = '';
this._isSaving = false;
this.serviceName = service;
this.Manager = new breeze.EntityManager(this.serviceName);
this.EntityQuery = new breeze.EntityQuery();
}
Dataservice.prototype.getAllMovies = function () {
this.EntityQuery = breeze.EntityQuery.from("AllMovies");
return this.Manager.executeQuery(this.EntityQuery);
};
Dataservice.prototype.createMovie = function (initialValues) {
return this.Manager.createEntity('tblMovies', initialValues); //THis is where it goes wrong :(
};
Dataservice.prototype.saveChanges = function (suppressLogIfNothingToSave) {
if (this.Manager.hasChanges()) {
if (this._isSaving) {
setTimeout(this.saveChanges, 50);
return;
}
this.Manager.saveChanges().then(this.saveSucceeded).fail(this.saveFailed).fin(this.saveFinished);
} else if (!suppressLogIfNothingToSave) {
}
};
Dataservice.prototype.saveSucceeded = function (saveResult) {
this._isSaving = false;
};
Dataservice.prototype.saveFailed = function (error) {
};
Dataservice.prototype.saveFinished = function () {
this._isSaving = false;
};
return Dataservice;
})();
return Dataservice;
})
I do have a model tblMovie
using System;
using System.ComponentModel.DataAnnotations;
namespace DurandalMovieApp.Models
{
public class tblMovie
{
[Key]
public int MovieID { get; set; }
public string Title { get; set; }
public string Director { get; set; }
}
}
Hope someone can help!
I think that the problem is that your entity is: tblMovie, not tblMovies.
Try replacing:
return this.Manager.createEntity('tblMovies', initialValues);
With:
return this.Manager.createEntity('tblMovie', initialValues);