Форк Rambox
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

675 lines
18 KiB

const darkreader = require("darkreader");
Ext.define("Rambox.view.main.MainController", {
extend: "Ext.app.ViewController",
alias: "controller.main",
initialize: function (tabPanel) {
const config = ipc.sendSync("getConfig");
if (config.darkreader) {
darkreader.enable();
} else {
darkreader.disable();
}
tabPanel.setTabPosition(config.tabbar_location);
tabPanel.setTabRotation(0);
var reorderer = tabPanel.plugins.find(function (plugin) {
return plugin.ptype == "tabreorderer";
});
if (reorderer !== undefined) {
const names = reorderer.container.getLayout().names;
reorderer.dd.dim = names.width;
reorderer.dd.startAttr = names.beforeX;
reorderer.dd.endAttr = names.afterX;
}
},
// Make focus on webview every time the user change tabs, to enable the autofocus in websites
onTabChange: function (tabPanel, newTab, oldTab) {
var me = this;
// Set Google Analytics event
ga_storage._trackPageview("/index.html", "main");
localStorage.setItem("last_active_service", newTab.id);
if (newTab.id === "ramboxTab") {
if (Rambox.app.getTotalNotifications() > 0) {
document.title = "Rambox (" + Rambox.app.getTotalNotifications() + ")";
} else {
document.title = "Rambox";
}
return;
}
if (!newTab.record.get("enabled")) {
return;
}
var webview = newTab.down("component").el.dom;
setTimeout(function () {
if (webview) {
tabPanel.getActiveTab().getWebView().blur();
tabPanel.getActiveTab().getWebView().focus();
}
}, 300);
// Update the main window so it includes the active tab title.
if (Rambox.app.getTotalNotifications() > 0) {
document.title =
"Rambox (" +
Rambox.app.getTotalNotifications() +
") - " +
newTab.record.get("name");
} else {
document.title = "Rambox - " + newTab.record.get("name");
}
},
updatePositions: function (tabPanel, tab) {
if (tab.id === "ramboxTab" || tab.id === "tbfill") return true;
console.log("Updating Tabs positions...");
var store = Ext.getStore("Services");
var align = "left";
store.suspendEvent("remove");
Ext.each(tabPanel.items.items, function (t, i) {
if (
t.id !== "ramboxTab" &&
t.id !== "tbfill" &&
t.record.get("enabled")
) {
var rec = store.getById(t.record.get("id"));
if (align === "right") i--;
rec.set("align", align);
rec.set("position", i);
rec.save();
} else if (t.id === "tbfill") {
align = "right";
}
});
store.load();
store.resumeEvent("remove");
},
showServiceTab: function (grid, record, tr, rowIndex, e) {
if (e.position.colIdx === 0) {
// Service Logo
Ext.getCmp("tab_" + record.get("id")).show();
}
},
onRenameService: function (editor, e) {
var me = this;
e.record.commit();
// Change the title of the Tab
Ext.getCmp("tab_" + e.record.get("id")).setTitle(e.record.get("name"));
},
onEnableDisableService: function (cc, rowIndex, checked, obj, hideTab) {
var rec = Ext.getStore("Services").getAt(rowIndex);
if (!checked) {
Ext.getCmp("tab_" + rec.get("id")).destroy();
} else {
Ext.cq1("app-main").insert(
rec.get("align") === "left"
? rec.get("position")
: rec.get("position") + 1,
{
xtype: "webview",
id: "tab_" + rec.get("id"),
title: rec.get("name"),
icon:
rec.get("type") !== "custom"
? "resources/icons/" + rec.get("logo")
: rec.get("logo") === ""
? "resources/icons/custom.png"
: rec.get("logo"),
src: rec.get("url"),
type: rec.get("type"),
muted: rec.get("muted"),
includeInGlobalUnreadCounter: rec.get("includeInGlobalUnreadCounter"),
displayTabUnreadCounter: rec.get("displayTabUnreadCounter"),
enabled: rec.get("enabled"),
record: rec,
useragent: ipc.sendSync("getConfig").user_agent,
hidden: hideTab,
tabConfig: {
service: rec,
},
}
);
}
},
onNewServiceSelect: function (view, record, item, index, e) {
Ext.create("Rambox.view.add.Add", {
record: record,
});
},
removeServiceFn: function (serviceId, total, actual, callback) {
var me = this;
if (!serviceId) return false;
// Get Record
var rec = Ext.getStore("Services").getById(serviceId);
if (!rec.get("enabled")) {
rec.set("enabled", true);
me.onEnableDisableService(
null,
Ext.getStore("Services").indexOf(rec),
true,
null,
true
);
// Get Tab
var tab = Ext.getCmp("tab_" + serviceId);
// Clear all trash data
const webview = tab.getWebView();
webview.addEventListener("did-start-loading", function () {
clearData(webview, tab);
});
} else {
// Get Tab
var tab = Ext.getCmp("tab_" + serviceId);
// Clear all trash data
const webview = tab.getWebView();
clearData(webview, tab);
}
const config = ipc.sendSync("getConfig");
if (config.default_service === rec.get("id"))
ipc.send(
"setConfig",
Ext.apply(config, { default_service: "ramboxTab" })
);
function clearData(webview, tab) {
const currentWebView = require("electron").remote.webContents.fromId(
webview.getWebContentsId()
);
currentWebView.clearHistory();
currentWebView.session.flushStorageData();
currentWebView.session
.clearCache()
.then(() => {
currentWebView.session
.clearStorageData()
.then(() => {
currentWebView.session.cookies
.flushStore()
.then(() => {
// Remove record from localStorage
Ext.getStore("Services").remove(rec);
// Close tab
tab.close();
// Close waiting message
if (total === actual) {
Ext.Msg.hide();
if (Ext.isFunction(callback)) callback();
}
})
.catch((err) => {
console.log(err);
});
})
.catch((err) => {
console.log(err);
});
})
.catch((err) => {
console.log(err);
});
}
},
removeService: function (gridView, rowIndex, colIndex, col, e, rec, rowEl) {
var me = this;
Ext.Msg.confirm(
locale["app.window[12]"],
locale["app.window[13]"] + " <b>" + rec.get("name") + "</b>?",
function (btnId) {
if (btnId === "yes") {
Ext.Msg.wait("Please wait until we clear all.", "Removing...");
me.removeServiceFn(rec.get("id"), 1, 1);
}
}
);
},
removeAllServices: function (btn, callback) {
var me = this;
if (btn) {
Ext.Msg.confirm(
locale["app.window[12]"],
locale["app.window[14]"],
function (btnId) {
if (btnId === "yes") {
// Clear counter for unread messaging
document.title = "Rambox";
Ext.cq1("app-main").suspendEvent("remove");
Ext.getStore("Services").load();
Ext.Msg.wait("Please wait until we clear all.", "Removing...");
const count = Ext.getStore("Services").getCount();
var i = 1;
Ext.Array.each(
Ext.getStore("Services").collect("id"),
function (serviceId) {
me.removeServiceFn(serviceId, count, i++, callback || false);
}
);
if (count === 0 && Ext.isFunction(callback)) callback();
Ext.cq1("app-main").resumeEvent("remove");
}
}
);
} else {
Ext.cq1("app-main").suspendEvent("remove");
Ext.getStore("Services").load();
const count = Ext.getStore("Services").getCount();
var i = 1;
Ext.Array.each(
Ext.getStore("Services").collect("id"),
function (serviceId) {
me.removeServiceFn(serviceId, count, i++, callback || false);
}
);
if (count === 0 && Ext.isFunction(callback)) callback();
Ext.cq1("app-main").resumeEvent("remove");
}
},
configureService: function (
gridView,
rowIndex,
colIndex,
col,
e,
rec,
rowEl
) {
Ext.create("Rambox.view.add.Add", {
record: rec,
service: Ext.getStore("ServicesList").getById(rec.get("type")),
edit: true,
});
},
onSearchRender: function (field) {
field.focus(false, 1000);
},
onSearchEnter: function (field, e) {
var me = this;
if (
e.getKey() == e.ENTER &&
Ext.getStore("ServicesList").getCount() === 2
) {
// Two because we always shows Custom Service option
me.onNewServiceSelect(
field.up().down("dataview"),
Ext.getStore("ServicesList").getAt(0)
);
me.onClearClick(field);
}
},
doTypeFilter: function (cg, newValue, oldValue) {
var me = this;
Ext.getStore("ServicesList")
.getFilters()
.replaceAll({
fn: function (record) {
return (
Ext.Array.contains(
Ext.Object.getKeys(cg.getValue()),
record.get("type")
) || record.get("type") === "custom"
);
},
});
},
onSearchServiceChange: function (field, newValue, oldValue) {
var me = this;
var cg = field.up().down("checkboxgroup");
if (!Ext.isEmpty(newValue) && newValue.length > 0) {
field.getTrigger("clear").show();
Ext.getStore("ServicesList")
.getFilters()
.replaceAll({
fn: function (record) {
if (record.get("type") === "custom") return true;
if (
!Ext.Array.contains(
Ext.Object.getKeys(cg.getValue()),
record.get("type")
)
)
return false;
return record
.get("name")
.toLowerCase()
.indexOf(newValue.toLowerCase()) > -1
? true
: false;
},
});
} else {
field.getTrigger("clear").hide();
Ext.getStore("ServicesList").getFilters().removeAll();
me.doTypeFilter(cg);
}
field.updateLayout();
},
onClearClick: function (field, trigger, e) {
var me = this;
var cg = field.up().down("checkboxgroup");
field.reset();
field.getTrigger("clear").hide();
field.updateLayout();
Ext.getStore("ServicesList").getFilters().removeAll();
me.doTypeFilter(cg);
},
dontDisturb: function (btn, e, called) {
console.info("Dont Disturb:", btn.pressed ? "Enabled" : "Disabled");
// Google Analytics Event
if (!called)
ga_storage._trackEvent(
"Usability",
"dontDisturb",
btn.pressed ? "on" : "off"
);
Ext.Array.each(
Ext.getStore("Services").collect("id"),
function (serviceId) {
// Get Tab
var tab = Ext.getCmp("tab_" + serviceId);
if (!tab) return; // Skip disabled services
// Mute sounds
tab.setAudioMuted(btn.pressed ? true : tab.record.get("muted"), true);
// Prevent Notifications
tab.setNotifications(
btn.pressed ? false : tab.record.get("notifications"),
true
);
}
);
localStorage.setItem("dontDisturb", btn.pressed);
ipc.send("setDontDisturb", btn.pressed);
btn.setText(
locale["app.main[16]"] +
": " +
(btn.pressed ? locale["app.window[20]"] : locale["app.window[21]"])
);
// var btn_icon = document.getElementById('disturbBtn-btnIconEl');
// btn_icon.innerHTML = btn.pressed ? "" : "";
btn.pressed
? btn.setGlyph("xf1f7@FontAwesome")
: btn.setGlyph("xf0f3@FontAwesome");
Ext.getCmp("mainTabBar").getEl().toggleCls("dontdisturb");
// If this method is called from Lock method, prevent showing toast
if (!e) return;
Ext.toast({
html: btn.pressed ? "ENABLED" : "DISABLED",
title: "Don't Disturb",
width: 200,
align: "t",
closable: false,
});
},
lockRambox: function (btn) {
var me = this;
if (ipc.sendSync("getConfig").master_password) {
Ext.Msg.confirm(
locale["app.main[19]"],
"Do you want to use the Master Password as your temporal password?",
function (btnId) {
if (btnId === "yes") {
setLock(ipc.sendSync("getConfig").master_password);
} else {
showTempPass();
}
}
);
} else {
showTempPass();
}
function showTempPass() {
var msgbox = Ext.Msg.prompt(
locale["app.main[19]"],
locale["app.window[22]"],
function (btnId, text) {
if (btnId === "ok") {
var msgbox2 = Ext.Msg.prompt(
locale["app.main[19]"],
locale["app.window[23]"],
function (btnId, text2) {
if (btnId === "ok") {
if (text !== text2) {
Ext.Msg.show({
title: locale["app.window[24]"],
message: locale["app.window[25]"],
icon: Ext.Msg.WARNING,
buttons: Ext.Msg.OK,
fn: me.lockRambox,
});
return false;
}
setLock(Rambox.util.MD5.encypt(text));
}
}
);
msgbox2.textField.inputEl.dom.type = "password";
}
}
);
msgbox.textField.inputEl.dom.type = "password";
}
function setLock(text) {
var ramboxTab = Ext.cq1("#ramboxTab");
// Related to issue #2065. Focusing in an sub frame is a workaround
if (ramboxTab.getWebView) {
ramboxTab.down("component").el.dom.executeJavaScript(`
var iframeFix = document.createElement('iframe');
document.body.appendChild(iframeFix);
iframeFix.focus();
document.body.removeChild(iframeFix);
`);
}
console.info("Lock Rambox:", "Enabled");
// Save encrypted password in localStorage to show locked when app is reopen
localStorage.setItem("locked", text);
// Google Analytics Event
ga_storage._trackEvent("Usability", "locked");
me.lookupReference("disturbBtn").setPressed(true);
me.dontDisturb(me.lookupReference("disturbBtn"), false, true);
me.showLockWindow();
}
},
showLockWindow: function () {
var me = this;
var validateFn = function () {
if (
localStorage.getItem("locked") ===
Rambox.util.MD5.encypt(winLock.down("textfield").getValue())
) {
console.info("Lock Rambox:", "Disabled");
localStorage.removeItem("locked");
winLock.close();
me.lookupReference("disturbBtn").setPressed(false);
me.dontDisturb(me.lookupReference("disturbBtn"), false);
} else {
winLock.down("textfield").reset();
winLock.down("textfield").markInvalid("Unlock password is invalid");
}
};
var winLock = Ext.create("Ext.window.Window", {
maximized: true,
closable: false,
resizable: false,
minimizable: false,
maximizable: false,
draggable: false,
onEsc: Ext.emptyFn,
layout: "center",
bodyStyle: "background-color:#2e658e;",
items: [
{
xtype: "container",
layout: "vbox",
items: [
{
xtype: "image",
src: "resources/Icon.png",
width: 256,
height: 256,
},
{
xtype: "component",
autoEl: {
tag: "h1",
html: locale["app.window[26]"],
style: "text-align:center;width:256px;",
},
},
{
xtype: "textfield",
inputType: "password",
width: 256,
listeners: {
specialkey: function (field, e) {
if (e.getKey() == e.ENTER) {
validateFn();
}
},
},
},
{
xtype: "button",
text: locale["app.window[27]"],
glyph: "xf13e@FontAwesome",
width: 256,
scale: "large",
handler: validateFn,
},
],
},
],
listeners: {
render: function (win) {
win.getEl().on("click", function () {
win.down("textfield").focus(100);
});
},
},
}).show();
winLock.down("textfield").focus(1000);
},
openPreferences: function (btn) {
var me = this;
Ext.create("Rambox.view.preferences.Preferences").show();
},
login: function (btn) {
var me = this;
Rambox.ux.Auth0.login();
},
logout: function (btn) {
var me = this;
var logoutFn = function (callback) {
Ext.Msg.wait(locale["app.window[37]"], locale["app.main[21]"]);
// Google Analytics Event
ga_storage._trackEvent("Users", "loggedOut");
// Logout from Auth0
Rambox.ux.Auth0.logout();
Ext.cq1("app-main").getViewModel().set("username", "");
Ext.cq1("app-main").getViewModel().set("avatar", "");
if (Ext.isFunction(callback)) {
callback(false, function () {
Ext.Msg.hide();
});
} else {
Ext.Msg.hide();
}
};
if (btn) {
Ext.Msg.confirm(
locale["app.main[21]"],
locale["app.window[38]"],
function (btnId) {
if (btnId === "yes") {
logoutFn(me.removeAllServices.bind(me));
}
}
);
} else {
logoutFn();
}
},
showDonate: function (btn) {
Signalayer.API.show("tChaoq3PwSG9wswhn");
},
});