/*
* Copyright (C) 2015 Actor LLC. <https://actor.im>
*/
package im.actor.core.js;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.user.client.Event;
import im.actor.core.Configuration;
import im.actor.core.Messenger;
import im.actor.core.api.rpc.ResponseLoadArchived;
import im.actor.core.entity.Avatar;
import im.actor.core.entity.Contact;
import im.actor.core.entity.Dialog;
import im.actor.core.entity.FileReference;
import im.actor.core.entity.Message;
import im.actor.core.entity.Peer;
import im.actor.core.entity.PeerType;
import im.actor.core.entity.SearchEntity;
import im.actor.core.entity.content.FastThumb;
import im.actor.core.js.entity.JsBlockedUser;
import im.actor.core.js.entity.JsCall;
import im.actor.core.js.entity.JsCounter;
import im.actor.core.js.entity.JsDialogGroup;
import im.actor.core.js.entity.JsEventBusCallback;
import im.actor.core.js.entity.JsOnlineGroup;
import im.actor.core.js.entity.JsOnlineUser;
import im.actor.core.js.entity.JsSearchEntity;
import im.actor.core.js.entity.JsSticker;
import im.actor.core.js.modules.JsFilesModule;
import im.actor.core.js.modules.JsBindingModule;
import im.actor.core.js.modules.JsBindedValue;
import im.actor.core.js.entity.JsContact;
import im.actor.core.js.entity.JsDialog;
import im.actor.core.js.entity.JsGroup;
import im.actor.core.js.entity.JsMessage;
import im.actor.core.js.entity.JsPeer;
import im.actor.core.js.entity.JsPeerInfo;
import im.actor.core.js.entity.JsTyping;
import im.actor.core.js.entity.JsUser;
import im.actor.core.js.entity.Placeholders;
import im.actor.core.js.images.JsImageResize;
import im.actor.core.js.images.JsResizeListener;
import im.actor.core.js.modules.JsIdleModule;
import im.actor.core.js.providers.electron.JsElectronApp;
import im.actor.core.js.providers.electron.JsElectronListener;
import im.actor.core.js.providers.notification.JsChromePush;
import im.actor.core.js.providers.notification.JsSafariPush;
import im.actor.core.js.providers.notification.PushSubscribeResult;
import im.actor.core.network.RpcCallback;
import im.actor.core.viewmodel.ConversationVM;
import im.actor.core.viewmodel.GroupVM;
import im.actor.core.viewmodel.UserVM;
import im.actor.runtime.Log;
import im.actor.runtime.Runtime;
import im.actor.runtime.Storage;
import im.actor.runtime.crypto.Base64Utils;
import im.actor.runtime.js.JsFileSystemProvider;
import im.actor.runtime.js.fs.JsBlob;
import im.actor.runtime.js.fs.JsFile;
import im.actor.runtime.js.mvvm.JsDisplayList;
import im.actor.runtime.mvvm.Value;
import im.actor.runtime.mvvm.ValueChangedListener;
import im.actor.runtime.threading.ThreadDispatcher;
public class JsMessenger extends Messenger {
private static final String TAG = "JsMessenger";
private static JsMessenger instance = null;
public static JsMessenger getInstance() {
return instance;
}
private JsIdleModule jsIdleModule;
private JsBindingModule jsBindingModule;
private JsFilesModule filesModule;
private JsFileSystemProvider fileSystemProvider;
private boolean isElectron;
public JsMessenger(Configuration configuration) {
super(configuration);
fileSystemProvider = (JsFileSystemProvider) Storage.getFileSystemRuntime();
filesModule = new JsFilesModule(modules);
jsBindingModule = new JsBindingModule(this, filesModule, modules);
isElectron = JsElectronApp.isElectron();
ThreadDispatcher.pushDispatcher(Runtime::postToMainThread);
jsIdleModule = new JsIdleModule(this, modules);
if (isElectron()) {
Log.d(TAG, "Init Electron IPC");
JsElectronApp.subscribe("window", new JsElectronListener() {
@Override
public void onEvent(String content) {
Log.d(TAG, "On Window " + content);
if ("focus".equals(content)) {
jsIdleModule.onVisible();
} else if ("blur".equals(content)) {
jsIdleModule.onHidden();
}
}
});
}
if (isElectron) {
getGlobalState().getGlobalTempCounter().subscribe(new ValueChangedListener<Integer>() {
@Override
public void onChanged(Integer val, Value<Integer> valueModel) {
if (val == null || val == 0) {
JsElectronApp.hideNewMessages();
} else {
JsElectronApp.updateBadge(val);
}
}
});
}
JsMessenger.instance = this;
}
public JsIdleModule getJsIdleModule() {
return jsIdleModule;
}
public boolean isElectron() {
return isElectron;
}
public void sendPhoto(final Peer peer, final String fileName, final JsBlob blob) {
Log.d(TAG, "Resizing photo");
JsImageResize.resize(blob, new JsResizeListener() {
@Override
public void onResized(String thumb, int thumbW, int thumbH, int fullW, int fullH) {
Log.d(TAG, "Photo resized");
int index = thumb.indexOf("base64,");
if (index < 0) {
Log.d(TAG, "Unable to find base64");
return;
}
String rawData = thumb.substring(index + "base64,".length());
byte[] thumbData = Base64Utils.fromBase64(rawData);
String descriptor = fileSystemProvider.registerUploadFile(blob);
sendPhoto(peer, fileName, fullW, fullH,
new FastThumb(thumbW, thumbH, thumbData),
descriptor);
}
});
}
public void sendPhoto(final Peer peer, final JsFile file) {
sendPhoto(peer, file.getName(), file);
}
public void sendAnimation(final Peer peer, final JsFile file) {
Log.d(TAG, "Resizing animation");
JsImageResize.resize(file, new JsResizeListener() {
@Override
public void onResized(String thumb, int thumbW, int thumbH, int fullW, int fullH) {
Log.d(TAG, "Animation resized");
int index = thumb.indexOf("base64,");
if (index < 0) {
Log.d(TAG, "Unable to find base64");
return;
}
String rawData = thumb.substring(index + "base64,".length());
byte[] thumbData = Base64Utils.fromBase64(rawData);
String descriptor = fileSystemProvider.registerUploadFile(file);
sendAnimation(peer, file.getName(), fullW, fullH,
new FastThumb(thumbW, thumbH, thumbData),
descriptor);
}
});
}
public void sendClipboardPhoto(final Peer peer, final JsBlob file) {
sendPhoto(peer, "clipboard.jpg", file);
}
public void loadMoreDialogs() {
modules.getMessagesModule().loadMoreDialogs();
}
public void loadArchivedDialogs(boolean init, RpcCallback<ResponseLoadArchived> callback) {
modules.getMessagesModule().loadMoreArchivedDialogs(init, callback);
}
public void loadMoreHistory(Peer peer) {
modules.getMessagesModule().loadMoreHistory(peer);
}
public JsBindedValue<JsUser> getJsUser(int uid) {
return jsBindingModule.getUser(uid);
}
public JsBindedValue<JsOnlineUser> getJsUserOnline(int gid) {
return jsBindingModule.getUserOnline(gid);
}
public JsBindedValue<JsBlockedUser> getJsUserBlocked(int uid) {
return jsBindingModule.getUserBlocked(uid);
}
public JsBindedValue<JsGroup> getJsGroup(int gid) {
return jsBindingModule.getGroup(gid);
}
public JsBindedValue<JsOnlineGroup> getJsGroupOnline(int gid) {
return jsBindingModule.getGroupOnline(gid);
}
public JsBindedValue<JsCall> getJsCall(String id) {
return jsBindingModule.getCall(id);
}
public JsBindedValue<JsTyping> getTyping(Peer peer) {
return jsBindingModule.getTyping(peer);
}
public JsBindedValue<String> getOnlineStatus() {
return jsBindingModule.getOnlineStatus();
}
public JsBindedValue<JsCounter> getGlobalCounter() {
return jsBindingModule.getGlobalCounter();
}
public JsBindedValue<JsCounter> getTempGlobalCounter() {
return jsBindingModule.getTempGlobalCounter();
}
public JsPeerInfo buildPeerInfo(Peer peer) {
if (peer.getPeerType() == PeerType.PRIVATE) {
UserVM userVM = getUsers().get(peer.getPeerId());
return JsPeerInfo.create(
JsPeer.create(peer),
userVM.getName().get(),
userVM.getNick().get(),
getSmallAvatarUrl(userVM.getAvatar().get()),
Placeholders.getPlaceholder(peer.getPeerId()),
userVM.getIsVerified().get());
} else if (peer.getPeerType() == PeerType.GROUP) {
GroupVM groupVM = getGroups().get(peer.getPeerId());
return JsPeerInfo.create(
JsPeer.create(peer),
groupVM.getName().get(),
null,
getSmallAvatarUrl(groupVM.getAvatar().get()),
Placeholders.getPlaceholder(peer.getPeerId()),
false);
} else {
throw new RuntimeException();
}
}
public JsDisplayList<JsDialog, Dialog> getSharedDialogList() {
return jsBindingModule.getSharedDialogList();
}
public JsDisplayList<JsContact, Contact> getSharedContactList() {
return jsBindingModule.getSharedContactList();
}
public JsDisplayList<JsSearchEntity, SearchEntity> getSharedSearchList() {
return jsBindingModule.getSharedSearchList();
}
public JsDisplayList<JsMessage, Message> getSharedChatList(Peer peer) {
return jsBindingModule.getSharedMessageList(peer);
}
public JsBindedValue<JsArray<JsDialogGroup>> getDialogsGroupedList() {
return jsBindingModule.getDialogsGroupedList();
}
public JsBindedValue<JsArray<JsSticker>> getStickers() {
return jsBindingModule.getStickers();
}
public void broadcastEvent(String tag, JavaScriptObject obj) {
jsBindingModule.broadcastEvent(tag, obj);
}
public void subscribeEventBus(JsEventBusCallback callback) {
jsBindingModule.subscribeEventBus(callback);
}
public void unsubscribeEventBus(JsEventBusCallback callback) {
jsBindingModule.unsubscribeEventBus(callback);
}
private String getSmallAvatarUrl(Avatar avatar) {
if (avatar != null && avatar.getSmallImage() != null) {
return getFileUrl(avatar.getSmallImage().getFileReference());
}
return null;
}
public String getFileUrl(FileReference fileReference) {
return filesModule.getFileUrl(fileReference.getFileId(), fileReference.getAccessHash());
}
}