mirror of
https://github.com/zulip/zulip-desktop.git
synced 2025-11-04 14:03:27 +00:00
Compare commits
1 Commits
v2.3.1
...
test-new-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
340da70868 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -7,13 +7,6 @@ node_modules/
|
|||||||
# Compiled binary build directory
|
# Compiled binary build directory
|
||||||
dist/
|
dist/
|
||||||
|
|
||||||
#snap generated files
|
|
||||||
snap/parts
|
|
||||||
snap/prime
|
|
||||||
snap/snap
|
|
||||||
snap/stage
|
|
||||||
snap/*.snap
|
|
||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ addons:
|
|||||||
|
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- '8'
|
- '6'
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- ./scripts/travis-xvfb.sh
|
- ./scripts/travis-xvfb.sh
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
const { app, dialog, shell } = require('electron');
|
const { app, dialog } = require('electron');
|
||||||
const { autoUpdater } = require('electron-updater');
|
const { autoUpdater } = require('electron-updater');
|
||||||
const isDev = require('electron-is-dev');
|
const isDev = require('electron-is-dev');
|
||||||
|
|
||||||
const ConfigUtil = require('./../renderer/js/utils/config-util.js');
|
const ConfigUtil = require('./../renderer/js/utils/config-util.js');
|
||||||
|
|
||||||
function appUpdater(updateFromMenu = false) {
|
function appUpdater() {
|
||||||
// Don't initiate auto-updates in development
|
// Don't initiate auto-updates in development
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
return;
|
return;
|
||||||
@@ -17,8 +17,6 @@ function appUpdater(updateFromMenu = false) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let updateAvailable = false;
|
|
||||||
|
|
||||||
// Create Logs directory
|
// Create Logs directory
|
||||||
const LogsDir = `${app.getPath('userData')}/Logs`;
|
const LogsDir = `${app.getPath('userData')}/Logs`;
|
||||||
|
|
||||||
@@ -30,58 +28,7 @@ function appUpdater(updateFromMenu = false) {
|
|||||||
autoUpdater.logger = log;
|
autoUpdater.logger = log;
|
||||||
|
|
||||||
// Handle auto updates for beta/pre releases
|
// Handle auto updates for beta/pre releases
|
||||||
const isBetaUpdate = ConfigUtil.getConfigItem('betaUpdate');
|
autoUpdater.allowPrerelease = ConfigUtil.getConfigItem('betaUpdate') || false;
|
||||||
|
|
||||||
autoUpdater.allowPrerelease = isBetaUpdate || false;
|
|
||||||
|
|
||||||
const eventsListenerRemove = ['update-available', 'update-not-available'];
|
|
||||||
autoUpdater.on('update-available', info => {
|
|
||||||
if (updateFromMenu) {
|
|
||||||
dialog.showMessageBox({
|
|
||||||
message: `A new version ${info.version}, of Zulip Desktop is available`,
|
|
||||||
detail: 'The update will be downloaded in the background. You will be notified when it is ready to be installed.'
|
|
||||||
});
|
|
||||||
|
|
||||||
updateAvailable = true;
|
|
||||||
|
|
||||||
// This is to prevent removal of 'update-downloaded' and 'error' event listener.
|
|
||||||
eventsListenerRemove.forEach(event => {
|
|
||||||
autoUpdater.removeAllListeners(event);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
autoUpdater.on('update-not-available', () => {
|
|
||||||
if (updateFromMenu) {
|
|
||||||
dialog.showMessageBox({
|
|
||||||
message: 'No updates available',
|
|
||||||
detail: `You are running the latest version of Zulip Desktop.\nVersion: ${app.getVersion()}`
|
|
||||||
});
|
|
||||||
// Remove all autoUpdator listeners so that next time autoUpdator is manually called these
|
|
||||||
// listeners don't trigger multiple times.
|
|
||||||
autoUpdater.removeAllListeners();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
autoUpdater.on('error', error => {
|
|
||||||
if (updateFromMenu) {
|
|
||||||
const messageText = (updateAvailable) ? ('Unable to download the updates') : ('Unable to check for updates');
|
|
||||||
dialog.showMessageBox({
|
|
||||||
type: 'error',
|
|
||||||
buttons: ['Manual Download', 'Cancel'],
|
|
||||||
message: messageText,
|
|
||||||
detail: (error).toString() + `\n\nThe latest version of Zulip Desktop is available at -\nhttps://zulipchat.com/apps/.\n
|
|
||||||
Current Version: ${app.getVersion()}`
|
|
||||||
}, response => {
|
|
||||||
if (response === 0) {
|
|
||||||
shell.openExternal('https://zulipchat.com/apps/');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Remove all autoUpdator listeners so that next time autoUpdator is manually called these
|
|
||||||
// listeners don't trigger multiple times.
|
|
||||||
autoUpdater.removeAllListeners();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Ask the user if update is available
|
// Ask the user if update is available
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const crashHandler = () => {
|
|||||||
productName: 'zulip-electron',
|
productName: 'zulip-electron',
|
||||||
companyName: 'Kandra Labs, Inc.',
|
companyName: 'Kandra Labs, Inc.',
|
||||||
submitURL: 'https://zulip-sentry.herokuapp.com/crashreport',
|
submitURL: 'https://zulip-sentry.herokuapp.com/crashreport',
|
||||||
uploadToServer: true
|
autoSubmit: true
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ const iconPath = () => {
|
|||||||
function createMainWindow() {
|
function createMainWindow() {
|
||||||
// Load the previous state with fallback to defaults
|
// Load the previous state with fallback to defaults
|
||||||
const mainWindowState = windowStateKeeper({
|
const mainWindowState = windowStateKeeper({
|
||||||
defaultWidth: 1100,
|
defaultWidth: 1000,
|
||||||
defaultHeight: 720
|
defaultHeight: 600
|
||||||
});
|
});
|
||||||
|
|
||||||
// Let's keep the window position global so that we can access it in other process
|
// Let's keep the window position global so that we can access it in other process
|
||||||
@@ -71,6 +71,7 @@ function createMainWindow() {
|
|||||||
minHeight: 400,
|
minHeight: 400,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
plugins: true,
|
plugins: true,
|
||||||
|
allowDisplayingInsecureContent: true,
|
||||||
nodeIntegration: true
|
nodeIntegration: true
|
||||||
},
|
},
|
||||||
show: false
|
show: false
|
||||||
@@ -131,9 +132,6 @@ function createMainWindow() {
|
|||||||
// Decrease load on GPU (experimental)
|
// Decrease load on GPU (experimental)
|
||||||
app.disableHardwareAcceleration();
|
app.disableHardwareAcceleration();
|
||||||
|
|
||||||
// Temporary fix for Electron render colors differently
|
|
||||||
app.commandLine.appendSwitch('force-color-profile', 'srgb');
|
|
||||||
|
|
||||||
// eslint-disable-next-line max-params
|
// eslint-disable-next-line max-params
|
||||||
app.on('certificate-error', (event, webContents, url, error, certificate, callback) => {
|
app.on('certificate-error', (event, webContents, url, error, certificate, callback) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -164,9 +162,7 @@ app.on('ready', () => {
|
|||||||
|
|
||||||
page.once('did-frame-finish-load', () => {
|
page.once('did-frame-finish-load', () => {
|
||||||
// Initate auto-updates on MacOS and Windows
|
// Initate auto-updates on MacOS and Windows
|
||||||
if (ConfigUtil.getConfigItem('autoUpdate')) {
|
|
||||||
appUpdater();
|
appUpdater();
|
||||||
}
|
|
||||||
crashHandler();
|
crashHandler();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
const os = require('os');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const { app, shell, BrowserWindow, Menu, dialog } = require('electron');
|
const { app, shell, BrowserWindow, Menu } = require('electron');
|
||||||
|
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const { appUpdater } = require('./autoupdater');
|
|
||||||
|
|
||||||
const ConfigUtil = require(__dirname + '/../renderer/js/utils/config-util.js');
|
const ConfigUtil = require(__dirname + '/../renderer/js/utils/config-util.js');
|
||||||
const DNDUtil = require(__dirname + '/../renderer/js/utils/dnd-util.js');
|
|
||||||
|
|
||||||
const appName = app.getName();
|
const appName = app.getName();
|
||||||
|
|
||||||
@@ -88,7 +87,7 @@ class AppMenu {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
label: 'Toggle Sidebar',
|
label: 'Toggle Sidebar',
|
||||||
accelerator: 'CommandOrControl+Shift+S',
|
accelerator: 'CommandOrControl+S',
|
||||||
click(item, focusedWindow) {
|
click(item, focusedWindow) {
|
||||||
if (focusedWindow) {
|
if (focusedWindow) {
|
||||||
const newValue = !ConfigUtil.getConfigItem('showSidebar');
|
const newValue = !ConfigUtil.getConfigItem('showSidebar');
|
||||||
@@ -140,11 +139,13 @@ class AppMenu {
|
|||||||
}, {
|
}, {
|
||||||
label: 'Report an Issue...',
|
label: 'Report an Issue...',
|
||||||
click() {
|
click() {
|
||||||
// the goal is to notify the main.html BrowserWindow
|
const body = `
|
||||||
// which may not be the focused window.
|
<!-- Please succinctly describe your issue and steps to reproduce it. -->
|
||||||
BrowserWindow.getAllWindows().forEach(window => {
|
-
|
||||||
window.webContents.send('open-feedback-modal');
|
${app.getName()} ${app.getVersion()}
|
||||||
});
|
Electron ${process.versions.electron}
|
||||||
|
${process.platform} ${process.arch} ${os.release()}`;
|
||||||
|
shell.openExternal(`https://github.com/zulip/zulip-electron/issues/new?body=${encodeURIComponent(body)}`);
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
@@ -196,11 +197,6 @@ class AppMenu {
|
|||||||
AppMenu.sendAction('open-about');
|
AppMenu.sendAction('open-about');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
|
||||||
label: `Check for Update`,
|
|
||||||
click() {
|
|
||||||
AppMenu.checkForUpdate();
|
|
||||||
}
|
|
||||||
}, {
|
}, {
|
||||||
type: 'separator'
|
type: 'separator'
|
||||||
}, {
|
}, {
|
||||||
@@ -221,13 +217,6 @@ class AppMenu {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
type: 'separator'
|
type: 'separator'
|
||||||
}, {
|
|
||||||
label: 'Toggle Do Not Disturb',
|
|
||||||
accelerator: 'Command+Shift+M',
|
|
||||||
click() {
|
|
||||||
const dndUtil = DNDUtil.toggle();
|
|
||||||
AppMenu.sendAction('toggle-dnd', dndUtil.dnd, dndUtil.newSettings);
|
|
||||||
}
|
|
||||||
}, {
|
}, {
|
||||||
label: 'Reset App Settings',
|
label: 'Reset App Settings',
|
||||||
accelerator: 'Command+Shift+D',
|
accelerator: 'Command+Shift+D',
|
||||||
@@ -308,11 +297,6 @@ class AppMenu {
|
|||||||
AppMenu.sendAction('open-about');
|
AppMenu.sendAction('open-about');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
|
||||||
label: `Check for Update`,
|
|
||||||
click() {
|
|
||||||
AppMenu.checkForUpdate();
|
|
||||||
}
|
|
||||||
}, {
|
}, {
|
||||||
type: 'separator'
|
type: 'separator'
|
||||||
}, {
|
}, {
|
||||||
@@ -335,13 +319,6 @@ class AppMenu {
|
|||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
type: 'separator'
|
type: 'separator'
|
||||||
}, {
|
|
||||||
label: 'Toggle Do Not Disturb',
|
|
||||||
accelerator: 'Ctrl+Shift+M',
|
|
||||||
click() {
|
|
||||||
const dndUtil = DNDUtil.toggle();
|
|
||||||
AppMenu.sendAction('toggle-dnd', dndUtil.dnd, dndUtil.newSettings);
|
|
||||||
}
|
|
||||||
}, {
|
}, {
|
||||||
label: 'Reset App Settings',
|
label: 'Reset App Settings',
|
||||||
accelerator: 'Ctrl+Shift+D',
|
accelerator: 'Ctrl+Shift+D',
|
||||||
@@ -410,23 +387,10 @@ class AppMenu {
|
|||||||
win.webContents.send(action, ...params);
|
win.webContents.send(action, ...params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static checkForUpdate() {
|
|
||||||
appUpdater(true);
|
|
||||||
}
|
|
||||||
static resetAppSettings() {
|
static resetAppSettings() {
|
||||||
const resetAppSettingsMessage = 'By proceeding you will be removing all connected organizations and preferences from Zulip.';
|
|
||||||
|
|
||||||
// We save App's settings/configurations in following files
|
// We save App's settings/configurations in following files
|
||||||
const settingFiles = ['window-state.json', 'domain.json', 'settings.json'];
|
const settingFiles = ['window-state.json', 'domain.json', 'settings.json'];
|
||||||
|
|
||||||
dialog.showMessageBox({
|
|
||||||
type: 'warning',
|
|
||||||
buttons: ['YES', 'NO'],
|
|
||||||
defaultId: 0,
|
|
||||||
message: 'Are you sure?',
|
|
||||||
detail: resetAppSettingsMessage
|
|
||||||
}, response => {
|
|
||||||
if (response === 0) {
|
|
||||||
settingFiles.forEach(settingFileName => {
|
settingFiles.forEach(settingFileName => {
|
||||||
const getSettingFilesPath = path.join(app.getPath('appData'), appName, settingFileName);
|
const getSettingFilesPath = path.join(app.getPath('appData'), appName, settingFileName);
|
||||||
fs.access(getSettingFilesPath, error => {
|
fs.access(getSettingFilesPath, error => {
|
||||||
@@ -440,8 +404,6 @@ class AppMenu {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setMenu(props) {
|
setMenu(props) {
|
||||||
const tpl = process.platform === 'darwin' ? this.getDarwinTpl(props) : this.getOtherTpl(props);
|
const tpl = process.platform === 'darwin' ? this.getDarwinTpl(props) : this.getOtherTpl(props);
|
||||||
|
|||||||
893
app/package-lock.json
generated
893
app/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "zulip",
|
"name": "zulip",
|
||||||
"productName": "Zulip",
|
"productName": "Zulip",
|
||||||
"version": "2.3.1",
|
"version": "1.8.2",
|
||||||
"description": "Zulip Desktop App",
|
"description": "Zulip Desktop App",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"copyright": "Kandra Labs, Inc.",
|
"copyright": "Kandra Labs, Inc.",
|
||||||
@@ -26,21 +26,19 @@
|
|||||||
"InstantMessaging"
|
"InstantMessaging"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@electron-elements/send-feedback": "1.0.7",
|
"auto-launch": "5.0.1",
|
||||||
"escape-html": "1.0.3",
|
|
||||||
"auto-launch": "5.0.5",
|
|
||||||
"electron-is-dev": "0.3.0",
|
"electron-is-dev": "0.3.0",
|
||||||
"electron-log": "2.2.14",
|
"electron-log": "2.2.7",
|
||||||
"electron-spellchecker": "1.1.2",
|
"electron-spellchecker": "1.1.2",
|
||||||
"electron-updater": "2.21.10",
|
"electron-updater": "2.18.2",
|
||||||
"electron-window-state": "4.1.1",
|
"electron-window-state": "4.1.1",
|
||||||
"is-online": "7.0.0",
|
"is-online": "7.0.0",
|
||||||
"node-json-db": "0.7.3",
|
"node-json-db": "0.7.3",
|
||||||
"request": "2.85.0",
|
"request": "2.81.0",
|
||||||
"semver": "5.4.1",
|
"semver": "5.4.1",
|
||||||
"wurl": "2.5.0"
|
"wurl": "2.5.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"node-mac-notifier": "0.1.0"
|
"node-mac-notifier": "0.0.13"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,19 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="css/about.css">
|
<link rel="stylesheet" href="css/about.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="about">
|
<div class="about">
|
||||||
<img class="logo" src="../resources/zulip.png" />
|
<img class="logo" src="../resources/zulip.png" />
|
||||||
<p class="detail" id="version">v?.?.?</p>
|
<p class="detail" id="version">v?.?.?</p>
|
||||||
<div class="maintenance-info">
|
<div class="maintenance-info">
|
||||||
<p class="detail maintainer">
|
<p class="detail maintainer">
|
||||||
Maintained by
|
Maintained by <a onclick="linkInBrowser('website')">Zulip</a>
|
||||||
<a onclick="linkInBrowser('website')">Zulip</a>
|
|
||||||
</p>
|
</p>
|
||||||
<p class="detail license">
|
<p class="detail license">
|
||||||
Available under the
|
Available under the <a onclick="linkInBrowser('license')">Apache 2.0 License</a>
|
||||||
<a onclick="linkInBrowser('license')">Apache 2.0 License</a>
|
|
||||||
</p>
|
</p>
|
||||||
<a class="bug" onclick="linkInBrowser('bug')" href="#">Found bug?</a>
|
<a class="bug" onclick="linkInBrowser('bug')" href="#">Found bug?</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -45,6 +41,5 @@
|
|||||||
shell.openExternal(url);
|
shell.openExternal(url);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script>require('./js/shared/preventdrag.js')</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ body {
|
|||||||
#content {
|
#content {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
background: #fff url(../img/ic_loading.gif) no-repeat;
|
||||||
|
background-size: 60px 60px;
|
||||||
|
background-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-sidebar {
|
.toggle-sidebar {
|
||||||
@@ -25,7 +28,7 @@ body {
|
|||||||
-webkit-app-region: drag;
|
-webkit-app-region: drag;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: all 0.5s ease;
|
transition: all 0.5s ease;
|
||||||
z-index: 2;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-sidebar div {
|
.toggle-sidebar div {
|
||||||
@@ -42,28 +45,6 @@ body {
|
|||||||
transition: all 0.6s ease-out;
|
transition: all 0.6s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#view-controls-container {
|
|
||||||
height: calc(100% - 208px);
|
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#view-controls-container:hover {
|
|
||||||
overflow-y: overlay;
|
|
||||||
}
|
|
||||||
|
|
||||||
#view-controls-container::-webkit-scrollbar {
|
|
||||||
width: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#view-controls-container::-webkit-scrollbar-track {
|
|
||||||
box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#view-controls-container::-webkit-scrollbar-thumb {
|
|
||||||
background-color: darkgrey;
|
|
||||||
outline: 1px solid slategrey;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Material Icons';
|
font-family: 'Material Icons';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -140,14 +121,11 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.action-button.active {
|
.action-button.active {
|
||||||
/* background-color: rgba(255, 255, 255, 0.25); */
|
background-color: rgba(255, 255, 255, 0.25);
|
||||||
background-color: #efefef;
|
|
||||||
opacity: 0.9;
|
|
||||||
padding-right: 14px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-button.active i {
|
.action-button.active i {
|
||||||
color: #1c262b;
|
color: #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab:first-child {
|
.tab:first-child {
|
||||||
@@ -270,63 +248,37 @@ body {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Pseudo element for loading indicator*/
|
|
||||||
#webviews-container::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
background: #fff url(../img/ic_loading.gif) no-repeat;
|
|
||||||
background-size: 60px 60px;
|
|
||||||
background-position: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*When the active webview is loaded*/
|
|
||||||
#webviews-container.loaded::before {
|
|
||||||
opacity: 0;
|
|
||||||
z-index: -1;
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
webview {
|
webview {
|
||||||
|
opacity: 1;
|
||||||
/* transition: opacity 0.3s ease-in; */
|
/* transition: opacity 0.3s ease-in; */
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
flex-grow: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
webview.onload {
|
webview.onload {
|
||||||
transition: opacity 1s cubic-bezier(0.95, 0.05, 0.795, 0.035);
|
transition: opacity 1s cubic-bezier(0.95, 0.05, 0.795, 0.035);
|
||||||
}
|
}
|
||||||
|
|
||||||
webview.active {
|
|
||||||
opacity: 1;
|
|
||||||
z-index: 1;
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
webview.disabled {
|
webview.disabled {
|
||||||
|
flex: 0 1;
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
webview.focus {
|
webview:focus {
|
||||||
outline: 0px solid transparent;
|
outline: 0px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Tooltip styling */
|
/* Tooltip styling */
|
||||||
|
|
||||||
#dnd-tooltip,
|
|
||||||
#back-tooltip,
|
#back-tooltip,
|
||||||
#reload-tooltip,
|
#reload-tooltip,
|
||||||
#setting-tooltip {
|
#setting-tooltip {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
background: #222c31;
|
background: #222c31;
|
||||||
margin-left: 48px;
|
margin-left: 45px;
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
@@ -338,7 +290,6 @@ webview.focus {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#dnd-tooltip:after,
|
|
||||||
#back-tooltip:after,
|
#back-tooltip:after,
|
||||||
#reload-tooltip:after,
|
#reload-tooltip:after,
|
||||||
#setting-tooltip:after {
|
#setting-tooltip:after {
|
||||||
@@ -399,8 +350,6 @@ webview.focus {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
flex-grow: 1;
|
|
||||||
flex-basis: 0px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
@@ -443,26 +392,3 @@ webview.focus {
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send-feedback {
|
|
||||||
width: 60%;
|
|
||||||
height: 85%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#feedback-modal {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(68, 67, 67, 0.81);
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 2;
|
|
||||||
transition: all 1s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#feedback-modal.show {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -95,13 +95,11 @@ td:nth-child(odd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#sidebar {
|
#sidebar {
|
||||||
width: 150px;
|
width: 80px;
|
||||||
min-width: 100px;
|
padding: 30px;
|
||||||
padding: 30px 30px 30px 35px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
background: #f2f2f2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-container {
|
#nav-container {
|
||||||
@@ -115,7 +113,7 @@ td:nth-child(odd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nav.active {
|
.nav.active {
|
||||||
color: #4ebfac;
|
color: #464e5a;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@@ -123,19 +121,12 @@ td:nth-child(odd) {
|
|||||||
.nav.active::before {
|
.nav.active::before {
|
||||||
background: #464e5a;
|
background: #464e5a;
|
||||||
width: 3px;
|
width: 3px;
|
||||||
height: 18px;
|
height: 16px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -8px;
|
left: -8px;
|
||||||
content: '';
|
content: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* We don't want to show this in nav item since we have the + button for adding an Organization */
|
|
||||||
|
|
||||||
#nav-AddServer {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#settings-header {
|
#settings-header {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
color: #222c31;
|
color: #222c31;
|
||||||
@@ -151,12 +142,12 @@ td:nth-child(odd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#new-server-container {
|
#new-server-container {
|
||||||
padding-left: 42px;
|
opacity: 1;
|
||||||
padding-top: 25px;
|
transition: opacity 0.3s;
|
||||||
margin-right: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
padding: 4px 0 6px 0;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #222c31;
|
color: #222c31;
|
||||||
}
|
}
|
||||||
@@ -168,16 +159,6 @@ td:nth-child(odd) {
|
|||||||
padding: 4px 0 6px 0;
|
padding: 4px 0 6px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-server-info-row {
|
|
||||||
display: flex;
|
|
||||||
margin: 8px 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-server-info-right {
|
|
||||||
flex-grow: 1;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sub-title {
|
.sub-title {
|
||||||
padding: 4px 0 6px 0;
|
padding: 4px 0 6px 0;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@@ -188,40 +169,20 @@ img.server-info-icon {
|
|||||||
width: 36px;
|
width: 36px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
cursor: pointer;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.server-info-left {
|
.server-info-left {
|
||||||
margin: 4px 20px 0 0;
|
margin: 10px 20px 0 0;
|
||||||
min-width: 40%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.server-info-right {
|
.server-info-right {
|
||||||
margin-top: 4px;
|
|
||||||
width: 55%;
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.server-info-row {
|
.server-info-row {
|
||||||
display: inline-block;
|
display: flex;
|
||||||
margin: 5px 0 0 0;
|
margin: 8px 0 0 0;
|
||||||
}
|
|
||||||
|
|
||||||
.server-info-left .server-info-row {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: inherit;
|
|
||||||
vertical-align: -2px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.server-url {
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.server-info-alias {
|
.server-info-alias {
|
||||||
@@ -229,10 +190,6 @@ img.server-info-icon {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.server-url-info {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting-input-key {
|
.setting-input-key {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
height: 27px;
|
height: 27px;
|
||||||
@@ -246,16 +203,18 @@ img.server-info-icon {
|
|||||||
.setting-input-value {
|
.setting-input-value {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
height: 22px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 13px;
|
padding: 7px;
|
||||||
border: #ededed 2px solid;
|
border: #ededed 2px solid;
|
||||||
outline-width: 0;
|
outline-width: 0;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
max-width: 450px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-input-value:focus {
|
.setting-input-value:focus {
|
||||||
border: #4EBFAC 2px solid;
|
border: #7cb980 2px solid;
|
||||||
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-block {
|
.setting-block {
|
||||||
@@ -311,7 +270,8 @@ img.server-info-icon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.settings-card:hover {
|
.settings-card:hover {
|
||||||
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 0px 0px rgba(0, 0, 0, 0.12);
|
/* border-left: 8px solid #bcbcbc; */
|
||||||
|
/* box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 0px 0px rgba(0, 0, 0, 0.12); */
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
@@ -320,15 +280,11 @@ img.server-info-icon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.red {
|
.red {
|
||||||
color: #ef5350;
|
color: #ffffff;
|
||||||
padding: 8px;
|
background: #ef5350;
|
||||||
border: rgba(239, 83, 80, 0.5) solid 1px;
|
padding: 3px;
|
||||||
}
|
padding-right: 10px;
|
||||||
|
padding-left: 10px;
|
||||||
.red:hover {
|
|
||||||
color: #e63431;
|
|
||||||
border: rgba(239, 83, 80, 0.7) solid 1px;
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.blue {
|
.blue {
|
||||||
@@ -358,8 +314,8 @@ img.server-info-icon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
i.open-tab-button {
|
i.open-tab-button {
|
||||||
padding-left: 2px;
|
padding: 0 5px;
|
||||||
font-size: 19px;
|
font-size: 18px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,10 +368,17 @@ i.open-tab-button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#open-create-org-link {
|
#open-create-org-link {
|
||||||
|
color: #666;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#open-create-org-link:hover {
|
||||||
|
color: #005580;
|
||||||
|
;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
.toggle {
|
.toggle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
margin-left: -9999px;
|
margin-left: -9999px;
|
||||||
@@ -470,110 +433,6 @@ input.toggle-round:checked+label:after {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Add new server modal */
|
|
||||||
|
|
||||||
.add-server-modal {
|
|
||||||
display: block;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 1;
|
|
||||||
padding-top: 15vh;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
margin: auto;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
/* background: rgba(61, 64, 67, 15); */
|
|
||||||
background: linear-gradient(35deg, #003b52, #45b59b);
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Modal Content */
|
|
||||||
|
|
||||||
.modal-container {
|
|
||||||
background-color: #f4f7f8;
|
|
||||||
margin: auto;
|
|
||||||
padding: 57px;
|
|
||||||
border: #dae1e3 1px solid;
|
|
||||||
width: 550px;
|
|
||||||
height: 370px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-server-modal .page-title {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 1.6rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.divider {
|
|
||||||
margin-bottom: 30px;
|
|
||||||
margin-top: 30px;
|
|
||||||
color: #7d878a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.divider hr {
|
|
||||||
margin-left: 8px;
|
|
||||||
margin-right: 8px;
|
|
||||||
width: 44%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.server-center {
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
align-items: center;
|
|
||||||
padding-top: 13px;
|
|
||||||
margin-left: -5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.server-center button {
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
margin: auto;
|
|
||||||
align-items: center;
|
|
||||||
text-align: center;
|
|
||||||
color: #fff;
|
|
||||||
background: #4EBFAC;
|
|
||||||
border-color: none;
|
|
||||||
border: none;
|
|
||||||
width: 98%;
|
|
||||||
height: 46px;
|
|
||||||
border-radius: 3px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.server-center button:hover {
|
|
||||||
background: #329588;
|
|
||||||
}
|
|
||||||
|
|
||||||
.server-center button:focus {
|
|
||||||
background: #329588;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip {
|
|
||||||
background-color: hsl(46,63%,95%);
|
|
||||||
border: 1px solid hsl(46,63%,84%);
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.md-14 {
|
|
||||||
font-size: 14px;
|
|
||||||
vertical-align: middle;
|
|
||||||
padding-right: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#open-hotkeys-link {
|
|
||||||
text-decoration: underline;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* responsive grid */
|
/* responsive grid */
|
||||||
|
|
||||||
@media (max-width: 650px) {
|
@media (max-width: 650px) {
|
||||||
@@ -587,53 +446,3 @@ input.toggle-round:checked+label:after {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 720px) {
|
|
||||||
.modal-container {
|
|
||||||
width: 60vw;
|
|
||||||
padding: 40px;
|
|
||||||
min-width: 300px;
|
|
||||||
}
|
|
||||||
.server-center button {
|
|
||||||
margin-right: -12px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.divider {
|
|
||||||
margin-right: -8px;
|
|
||||||
}
|
|
||||||
.divider hr {
|
|
||||||
margin-left: 6px;
|
|
||||||
margin-right: 6px;
|
|
||||||
width: 43%;
|
|
||||||
}
|
|
||||||
#new-server-container {
|
|
||||||
padding-left: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
.divider {
|
|
||||||
margin-left: 4%;
|
|
||||||
}
|
|
||||||
.divider hr {
|
|
||||||
margin-left: 2px;
|
|
||||||
margin-right: 2px;
|
|
||||||
width: 40%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 900px) {
|
|
||||||
.settings-card {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.server-info-right {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
const { shell } = require('electron').remote;
|
|
||||||
const LinkUtil = require('../utils/link-util');
|
|
||||||
const DomainUtil = require('../utils/domain-util');
|
|
||||||
|
|
||||||
function handleExternalLink(event) {
|
|
||||||
const { url } = event;
|
|
||||||
const domainPrefix = DomainUtil.getDomain(this.props.index).url;
|
|
||||||
|
|
||||||
// Whitelist URLs which are allowed to be opened in the app
|
|
||||||
const {
|
|
||||||
isInternalUrl: isWhiteListURL,
|
|
||||||
isUploadsUrl: isUploadsURL
|
|
||||||
} = LinkUtil.isInternal(domainPrefix, url);
|
|
||||||
|
|
||||||
if (isWhiteListURL) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
// download txt, pdf, mp3, mp4 etc.. by using downloadURL in the
|
|
||||||
// main process which allows the user to save the files to their desktop
|
|
||||||
// and not trigger webview reload while image in webview will
|
|
||||||
// do nothing and will not save it
|
|
||||||
if (!LinkUtil.isImage(url) && isUploadsURL) {
|
|
||||||
this.$el.downloadURL(url);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// open internal urls inside the current webview.
|
|
||||||
this.$el.loadURL(url);
|
|
||||||
} else {
|
|
||||||
event.preventDefault();
|
|
||||||
shell.openExternal(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = handleExternalLink;
|
|
||||||
@@ -3,12 +3,13 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const DomainUtil = require(__dirname + '/../utils/domain-util.js');
|
||||||
const ConfigUtil = require(__dirname + '/../utils/config-util.js');
|
const ConfigUtil = require(__dirname + '/../utils/config-util.js');
|
||||||
const SystemUtil = require(__dirname + '/../utils/system-util.js');
|
const SystemUtil = require(__dirname + '/../utils/system-util.js');
|
||||||
const { app, dialog } = require('electron').remote;
|
const LinkUtil = require(__dirname + '/../utils/link-util.js');
|
||||||
|
const { shell, app, dialog } = require('electron').remote;
|
||||||
|
|
||||||
const BaseComponent = require(__dirname + '/../components/base.js');
|
const BaseComponent = require(__dirname + '/../components/base.js');
|
||||||
const handleExternalLink = require(__dirname + '/../components/handle-external-link.js');
|
|
||||||
|
|
||||||
const shouldSilentWebview = ConfigUtil.getConfigItem('silent');
|
const shouldSilentWebview = ConfigUtil.getConfigItem('silent');
|
||||||
class WebView extends BaseComponent {
|
class WebView extends BaseComponent {
|
||||||
@@ -18,10 +19,9 @@ class WebView extends BaseComponent {
|
|||||||
this.props = props;
|
this.props = props;
|
||||||
|
|
||||||
this.zoomFactor = 1.0;
|
this.zoomFactor = 1.0;
|
||||||
this.loading = true;
|
this.loading = false;
|
||||||
this.badgeCount = 0;
|
this.badgeCount = 0;
|
||||||
this.customCSS = ConfigUtil.getConfigItem('customCSS');
|
this.customCSS = ConfigUtil.getConfigItem('customCSS');
|
||||||
this.$webviewsContainer = document.querySelector('#webviews-container').classList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template() {
|
template() {
|
||||||
@@ -46,7 +46,16 @@ class WebView extends BaseComponent {
|
|||||||
|
|
||||||
registerListeners() {
|
registerListeners() {
|
||||||
this.$el.addEventListener('new-window', event => {
|
this.$el.addEventListener('new-window', event => {
|
||||||
handleExternalLink.call(this, event);
|
const { url } = event;
|
||||||
|
const domainPrefix = DomainUtil.getDomain(this.props.index).url;
|
||||||
|
|
||||||
|
if (LinkUtil.isInternal(domainPrefix, url) || url === (domainPrefix + '/')) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.$el.loadURL(url);
|
||||||
|
} else {
|
||||||
|
event.preventDefault();
|
||||||
|
shell.openExternal(url);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (shouldSilentWebview) {
|
if (shouldSilentWebview) {
|
||||||
@@ -87,7 +96,6 @@ class WebView extends BaseComponent {
|
|||||||
if (this.props.role === 'server') {
|
if (this.props.role === 'server') {
|
||||||
this.$el.classList.add('onload');
|
this.$el.classList.add('onload');
|
||||||
}
|
}
|
||||||
this.loading = false;
|
|
||||||
this.show();
|
this.show();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -121,21 +129,14 @@ class WebView extends BaseComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// To show or hide the loading indicator in the the active tab
|
|
||||||
if (this.loading) {
|
|
||||||
this.$webviewsContainer.remove('loaded');
|
|
||||||
} else {
|
|
||||||
this.$webviewsContainer.add('loaded');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$el.classList.remove('disabled');
|
this.$el.classList.remove('disabled');
|
||||||
this.$el.classList.add('active');
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.props.role === 'server') {
|
if (this.props.role === 'server') {
|
||||||
this.$el.classList.remove('onload');
|
this.$el.classList.remove('onload');
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
this.focus();
|
this.focus();
|
||||||
|
this.loading = false;
|
||||||
this.props.onTitleChange();
|
this.props.onTitleChange();
|
||||||
// Injecting preload css in webview to override some css rules
|
// Injecting preload css in webview to override some css rules
|
||||||
this.$el.insertCSS(fs.readFileSync(path.join(__dirname, '/../../css/preload.css'), 'utf8'));
|
this.$el.insertCSS(fs.readFileSync(path.join(__dirname, '/../../css/preload.css'), 'utf8'));
|
||||||
@@ -167,7 +168,6 @@ class WebView extends BaseComponent {
|
|||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
this.$el.classList.add('disabled');
|
this.$el.classList.add('disabled');
|
||||||
this.$el.classList.remove('active');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
load() {
|
load() {
|
||||||
@@ -228,9 +228,6 @@ class WebView extends BaseComponent {
|
|||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
this.hide();
|
this.hide();
|
||||||
// Shows the loading indicator till the webview is reloaded
|
|
||||||
this.$webviewsContainer.remove('loaded');
|
|
||||||
this.loading = true;
|
|
||||||
this.$el.reload();
|
this.$el.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,62 +0,0 @@
|
|||||||
const { app } = require('electron').remote;
|
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
const SendFeedback = require('@electron-elements/send-feedback');
|
|
||||||
|
|
||||||
// make the button color match zulip app's theme
|
|
||||||
SendFeedback.customStyles = `
|
|
||||||
button:hover, button:focus {
|
|
||||||
border-color: #4EBFAC;
|
|
||||||
color: #4EBFAC;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:active {
|
|
||||||
background-color: #f1f1f1;
|
|
||||||
color: #4EBFAC;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
background-color: #4EBFAC;
|
|
||||||
border-color: #4EBFAC;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
customElements.define('send-feedback', SendFeedback);
|
|
||||||
const sendFeedback = document.querySelector('send-feedback');
|
|
||||||
const feedbackHolder = sendFeedback.parentElement;
|
|
||||||
|
|
||||||
// customize the fields of custom elements
|
|
||||||
sendFeedback.title = 'Report Issue';
|
|
||||||
sendFeedback.titleLabel = 'Issue title:';
|
|
||||||
sendFeedback.titlePlaceholder = 'Enter issue title';
|
|
||||||
sendFeedback.textareaLabel = 'Describe the issue:';
|
|
||||||
sendFeedback.textareaPlaceholder = 'Succinctly describe your issue and steps to reproduce it...';
|
|
||||||
sendFeedback.buttonLabel = 'Report Issue';
|
|
||||||
sendFeedback.loaderSuccessText = '';
|
|
||||||
|
|
||||||
sendFeedback.useReporter('emailReporter', {
|
|
||||||
email: 'akash@zulipchat.com'
|
|
||||||
});
|
|
||||||
|
|
||||||
feedbackHolder.addEventListener('click', e => {
|
|
||||||
// only remove the class if the grey out faded
|
|
||||||
// part is clicked and not the feedback element itself
|
|
||||||
if (e.target === e.currentTarget) {
|
|
||||||
feedbackHolder.classList.remove('show');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
sendFeedback.addEventListener('feedback-submitted', () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
feedbackHolder.classList.remove('show');
|
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
|
|
||||||
const dataDir = app.getPath('userData');
|
|
||||||
const logsDir = path.join(dataDir, '/Logs');
|
|
||||||
sendFeedback.logs.push(...fs.readdirSync(logsDir).map(file => path.join(logsDir, file)));
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
feedbackHolder,
|
|
||||||
sendFeedback
|
|
||||||
};
|
|
||||||
@@ -11,9 +11,7 @@ const WebView = require(__dirname + '/js/components/webview.js');
|
|||||||
const ServerTab = require(__dirname + '/js/components/server-tab.js');
|
const ServerTab = require(__dirname + '/js/components/server-tab.js');
|
||||||
const FunctionalTab = require(__dirname + '/js/components/functional-tab.js');
|
const FunctionalTab = require(__dirname + '/js/components/functional-tab.js');
|
||||||
const ConfigUtil = require(__dirname + '/js/utils/config-util.js');
|
const ConfigUtil = require(__dirname + '/js/utils/config-util.js');
|
||||||
const DNDUtil = require(__dirname + '/js/utils/dnd-util.js');
|
|
||||||
const ReconnectUtil = require(__dirname + '/js/utils/reconnect-util.js');
|
const ReconnectUtil = require(__dirname + '/js/utils/reconnect-util.js');
|
||||||
const { feedbackHolder } = require(__dirname + '/js/feedback.js');
|
|
||||||
|
|
||||||
class ServerManagerView {
|
class ServerManagerView {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -25,14 +23,12 @@ class ServerManagerView {
|
|||||||
this.$settingsButton = $actionsContainer.querySelector('#settings-action');
|
this.$settingsButton = $actionsContainer.querySelector('#settings-action');
|
||||||
this.$webviewsContainer = document.getElementById('webviews-container');
|
this.$webviewsContainer = document.getElementById('webviews-container');
|
||||||
this.$backButton = $actionsContainer.querySelector('#back-action');
|
this.$backButton = $actionsContainer.querySelector('#back-action');
|
||||||
this.$dndButton = $actionsContainer.querySelector('#dnd-action');
|
|
||||||
|
|
||||||
this.$addServerTooltip = document.getElementById('add-server-tooltip');
|
this.$addServerTooltip = document.getElementById('add-server-tooltip');
|
||||||
this.$reloadTooltip = $actionsContainer.querySelector('#reload-tooltip');
|
this.$reloadTooltip = $actionsContainer.querySelector('#reload-tooltip');
|
||||||
this.$settingsTooltip = $actionsContainer.querySelector('#setting-tooltip');
|
this.$settingsTooltip = $actionsContainer.querySelector('#setting-tooltip');
|
||||||
this.$serverIconTooltip = document.getElementsByClassName('server-tooltip');
|
this.$serverIconTooltip = document.getElementsByClassName('server-tooltip');
|
||||||
this.$backTooltip = $actionsContainer.querySelector('#back-tooltip');
|
this.$backTooltip = $actionsContainer.querySelector('#back-tooltip');
|
||||||
this.$dndTooltip = $actionsContainer.querySelector('#dnd-tooltip');
|
|
||||||
|
|
||||||
this.$sidebar = document.getElementById('sidebar');
|
this.$sidebar = document.getElementById('sidebar');
|
||||||
|
|
||||||
@@ -89,15 +85,9 @@ class ServerManagerView {
|
|||||||
startMinimized: false,
|
startMinimized: false,
|
||||||
enableSpellchecker: true,
|
enableSpellchecker: true,
|
||||||
showNotification: true,
|
showNotification: true,
|
||||||
autoUpdate: true,
|
|
||||||
betaUpdate: false,
|
betaUpdate: false,
|
||||||
silent: false,
|
silent: false,
|
||||||
lastActiveTab: 0,
|
lastActiveTab: 0
|
||||||
dnd: false,
|
|
||||||
dndPreviousSettings: {
|
|
||||||
showNotification: true,
|
|
||||||
silent: false
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Platform specific settings
|
// Platform specific settings
|
||||||
@@ -105,7 +95,6 @@ class ServerManagerView {
|
|||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
// Only available on Windows
|
// Only available on Windows
|
||||||
settingOptions.flashTaskbarOnMessage = true;
|
settingOptions.flashTaskbarOnMessage = true;
|
||||||
settingOptions.dndPreviousSettings.flashTaskbarOnMessage = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const i in settingOptions) {
|
for (const i in settingOptions) {
|
||||||
@@ -133,7 +122,7 @@ class ServerManagerView {
|
|||||||
// Remove focus from the settings icon at sidebar bottom
|
// Remove focus from the settings icon at sidebar bottom
|
||||||
this.$settingsButton.classList.remove('active');
|
this.$settingsButton.classList.remove('active');
|
||||||
} else {
|
} else {
|
||||||
this.openSettings('AddServer');
|
this.openSettings('Servers');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,16 +155,11 @@ class ServerManagerView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
initActions() {
|
initActions() {
|
||||||
this.initDNDButton();
|
|
||||||
this.$dndButton.addEventListener('click', () => {
|
|
||||||
const dndUtil = DNDUtil.toggle();
|
|
||||||
ipcRenderer.send('forward-message', 'toggle-dnd', dndUtil.dnd, dndUtil.newSettings);
|
|
||||||
});
|
|
||||||
this.$reloadButton.addEventListener('click', () => {
|
this.$reloadButton.addEventListener('click', () => {
|
||||||
this.tabs[this.activeTabIndex].webview.reload();
|
this.tabs[this.activeTabIndex].webview.reload();
|
||||||
});
|
});
|
||||||
this.$addServerButton.addEventListener('click', () => {
|
this.$addServerButton.addEventListener('click', () => {
|
||||||
this.openSettings('AddServer');
|
this.openSettings('Servers');
|
||||||
});
|
});
|
||||||
this.$settingsButton.addEventListener('click', () => {
|
this.$settingsButton.addEventListener('click', () => {
|
||||||
this.openSettings('General');
|
this.openSettings('General');
|
||||||
@@ -191,16 +175,10 @@ class ServerManagerView {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.sidebarHoverEvent(this.$addServerButton, this.$addServerTooltip, true);
|
this.sidebarHoverEvent(this.$addServerButton, this.$addServerTooltip);
|
||||||
this.sidebarHoverEvent(this.$settingsButton, this.$settingsTooltip);
|
this.sidebarHoverEvent(this.$settingsButton, this.$settingsTooltip);
|
||||||
this.sidebarHoverEvent(this.$reloadButton, this.$reloadTooltip);
|
this.sidebarHoverEvent(this.$reloadButton, this.$reloadTooltip);
|
||||||
this.sidebarHoverEvent(this.$backButton, this.$backTooltip);
|
this.sidebarHoverEvent(this.$backButton, this.$backTooltip);
|
||||||
this.sidebarHoverEvent(this.$dndButton, this.$dndTooltip);
|
|
||||||
}
|
|
||||||
|
|
||||||
initDNDButton() {
|
|
||||||
const dnd = ConfigUtil.getConfigItem('dnd', false);
|
|
||||||
this.toggleDNDButton(dnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getTabIndex() {
|
getTabIndex() {
|
||||||
@@ -209,17 +187,9 @@ class ServerManagerView {
|
|||||||
return currentIndex;
|
return currentIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
sidebarHoverEvent(SidebarButton, SidebarTooltip, addServer = false) {
|
sidebarHoverEvent(SidebarButton, SidebarTooltip) {
|
||||||
SidebarButton.addEventListener('mouseover', () => {
|
SidebarButton.addEventListener('mouseover', () => {
|
||||||
SidebarTooltip.removeAttribute('style');
|
SidebarTooltip.removeAttribute('style');
|
||||||
// To handle position of add server tooltip due to scrolling of list of organizations
|
|
||||||
// This could not be handled using CSS, hence the top of the tooltip is made same
|
|
||||||
// as that of its parent element.
|
|
||||||
// This needs to handled only for the add server tooltip and not others.
|
|
||||||
if (addServer) {
|
|
||||||
const { top } = SidebarButton.getBoundingClientRect();
|
|
||||||
SidebarTooltip.style.top = top + 'px';
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
SidebarButton.addEventListener('mouseout', () => {
|
SidebarButton.addEventListener('mouseout', () => {
|
||||||
SidebarTooltip.style.display = 'none';
|
SidebarTooltip.style.display = 'none';
|
||||||
@@ -227,13 +197,8 @@ class ServerManagerView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onHover(index, serverName) {
|
onHover(index, serverName) {
|
||||||
this.$serverIconTooltip[index].innerText = serverName;
|
this.$serverIconTooltip[index].innerHTML = serverName;
|
||||||
this.$serverIconTooltip[index].removeAttribute('style');
|
this.$serverIconTooltip[index].removeAttribute('style');
|
||||||
// To handle position of servers' tooltip due to scrolling of list of organizations
|
|
||||||
// This could not be handled using CSS, hence the top of the tooltip is made same
|
|
||||||
// as that of its parent element.
|
|
||||||
const { top } = this.$serverIconTooltip[index].parentElement.getBoundingClientRect();
|
|
||||||
this.$serverIconTooltip[index].style.top = top + 'px';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onHoverOut(index) {
|
onHoverOut(index) {
|
||||||
@@ -273,9 +238,6 @@ class ServerManagerView {
|
|||||||
preload: false
|
preload: false
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
// To show loading indicator the first time a functional tab is opened, indicator is
|
|
||||||
// closed when the functional tab DOM is ready, handled in webview.js
|
|
||||||
this.$webviewsContainer.classList.remove('loaded');
|
|
||||||
this.activateTab(this.functionalTabs[tabProps.name]);
|
this.activateTab(this.functionalTabs[tabProps.name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,10 +268,10 @@ class ServerManagerView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
activateLastTab(index) {
|
activateLastTab(index) {
|
||||||
// Open all the tabs in background, also activate the tab based on the index
|
// Open last active tab
|
||||||
this.activateTab(index);
|
|
||||||
// Save last active tab
|
|
||||||
ConfigUtil.setConfigItem('lastActiveTab', index);
|
ConfigUtil.setConfigItem('lastActiveTab', index);
|
||||||
|
// Open all the tabs in background
|
||||||
|
this.activateTab(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
activateTab(index, hideOldTab = true) {
|
activateTab(index, hideOldTab = true) {
|
||||||
@@ -349,7 +311,7 @@ class ServerManagerView {
|
|||||||
webContents.send('toggle-sidebar', state);
|
webContents.send('toggle-sidebar', state);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on('toggle-silent', (event, state) => {
|
ipcRenderer.on('toogle-silent', (event, state) => {
|
||||||
const webviews = document.querySelectorAll('webview');
|
const webviews = document.querySelectorAll('webview');
|
||||||
webviews.forEach(webview => {
|
webviews.forEach(webview => {
|
||||||
try {
|
try {
|
||||||
@@ -362,15 +324,6 @@ class ServerManagerView {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on('toggle-dnd', (event, state, newSettings) => {
|
|
||||||
this.toggleDNDButton(state);
|
|
||||||
ipcRenderer.send('forward-message', 'toggle-silent', newSettings.silent);
|
|
||||||
const selector = 'webview:not([class*=disabled])';
|
|
||||||
const webview = document.querySelector(selector);
|
|
||||||
const webContents = webview.getWebContents();
|
|
||||||
webContents.send('toggle-dnd', state, newSettings);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroyTab(name, index) {
|
destroyTab(name, index) {
|
||||||
@@ -390,9 +343,6 @@ class ServerManagerView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroyView() {
|
destroyView() {
|
||||||
// Show loading indicator
|
|
||||||
this.$webviewsContainer.classList.remove('loaded');
|
|
||||||
|
|
||||||
// Clear global variables
|
// Clear global variables
|
||||||
this.activeTabIndex = -1;
|
this.activeTabIndex = -1;
|
||||||
this.tabs = [];
|
this.tabs = [];
|
||||||
@@ -440,12 +390,6 @@ class ServerManagerView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggles the dnd button icon.
|
|
||||||
toggleDNDButton(alert) {
|
|
||||||
this.$dndTooltip.textContent = (alert ? 'Turn Off' : 'Enable') + ' Do Not Disturb';
|
|
||||||
this.$dndButton.querySelector('i').textContent = alert ? 'notifications_off' : 'notifications';
|
|
||||||
}
|
|
||||||
|
|
||||||
registerIpcs() {
|
registerIpcs() {
|
||||||
const webviewListeners = {
|
const webviewListeners = {
|
||||||
'webview-reload': 'reload',
|
'webview-reload': 'reload',
|
||||||
@@ -552,10 +496,6 @@ class ServerManagerView {
|
|||||||
}
|
}
|
||||||
ipcRenderer.send('update-taskbar-icon', createOverlayIcon(messageCount).toDataURL(), String(messageCount));
|
ipcRenderer.send('update-taskbar-icon', createOverlayIcon(messageCount).toDataURL(), String(messageCount));
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on('open-feedback-modal', () => {
|
|
||||||
feedbackHolder.classList.add('show');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
const BaseSection = require(__dirname + '/base-section.js');
|
const BaseSection = require(__dirname + '/base-section.js');
|
||||||
const DomainUtil = require(__dirname + '/../../utils/domain-util.js');
|
const DomainUtil = require(__dirname + '/../../utils/domain-util.js');
|
||||||
const ServerInfoForm = require(__dirname + '/server-info-form.js');
|
const ServerInfoForm = require(__dirname + '/server-info-form.js');
|
||||||
|
const CreateOrganziation = require(__dirname + '/create-new-org.js');
|
||||||
|
|
||||||
class ConnectedOrgSection extends BaseSection {
|
class AddedSection extends BaseSection {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super();
|
super();
|
||||||
this.props = props;
|
this.props = props;
|
||||||
@@ -13,9 +14,10 @@ class ConnectedOrgSection extends BaseSection {
|
|||||||
template() {
|
template() {
|
||||||
return `
|
return `
|
||||||
<div class="settings-pane" id="server-settings-pane">
|
<div class="settings-pane" id="server-settings-pane">
|
||||||
<div class="page-title">Connected organizations</div>
|
<div id="new-server-container"></div>
|
||||||
<div class="title" id="existing-servers">All the connected orgnizations will appear here.</div>
|
<div class="title" id="existing-servers"></div>
|
||||||
<div id="server-info-container"></div>
|
<div id="server-info-container"></div>
|
||||||
|
<div id="create-organization-container"></div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -32,9 +34,12 @@ class ConnectedOrgSection extends BaseSection {
|
|||||||
this.$serverInfoContainer = document.getElementById('server-info-container');
|
this.$serverInfoContainer = document.getElementById('server-info-container');
|
||||||
this.$existingServers = document.getElementById('existing-servers');
|
this.$existingServers = document.getElementById('existing-servers');
|
||||||
|
|
||||||
const noServerText = 'All the connected orgnizations will appear here';
|
this.$serverInfoContainer.innerHTML = servers.length ? '' : '';
|
||||||
// Show noServerText if no servers are there otherwise hide it
|
// Show Existing servers if servers are there otherwise hide it
|
||||||
this.$existingServers.innerHTML = servers.length === 0 ? noServerText : '';
|
this.$existingServers.innerHTML = servers.length === 0 ? '' : 'Connected organizations';
|
||||||
|
|
||||||
|
this.$createOrganizationContainer = document.getElementById('create-organization-container');
|
||||||
|
this.initCreateNewOrganization();
|
||||||
|
|
||||||
for (let i = 0; i < servers.length; i++) {
|
for (let i = 0; i < servers.length; i++) {
|
||||||
new ServerInfoForm({
|
new ServerInfoForm({
|
||||||
@@ -46,6 +51,11 @@ class ConnectedOrgSection extends BaseSection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initCreateNewOrganization() {
|
||||||
|
new CreateOrganziation({
|
||||||
|
$root: this.$createOrganizationContainer
|
||||||
|
}).init();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ConnectedOrgSection;
|
module.exports = AddedSection;
|
||||||
37
app/renderer/js/pages/preference/create-new-org.js
Normal file
37
app/renderer/js/pages/preference/create-new-org.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const BaseComponent = require(__dirname + '/../../components/base.js');
|
||||||
|
const shell = require('electron').shell;
|
||||||
|
|
||||||
|
class CreateOrganziation extends BaseComponent {
|
||||||
|
constructor(props) {
|
||||||
|
super();
|
||||||
|
this.props = props;
|
||||||
|
}
|
||||||
|
|
||||||
|
template() {
|
||||||
|
return `
|
||||||
|
<div class="setting-row">
|
||||||
|
<div class="setting-description">
|
||||||
|
<span id="open-create-org-link">Or create a new organization on zulipchat.com<i class="material-icons open-tab-button">open_in_new</i></span>
|
||||||
|
</div>
|
||||||
|
<div class="setting-control"></div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.props.$root.innerHTML = this.template();
|
||||||
|
this.openCreateNewOrgExternalLink();
|
||||||
|
}
|
||||||
|
|
||||||
|
openCreateNewOrgExternalLink() {
|
||||||
|
const link = 'https://zulipchat.com/beta/';
|
||||||
|
const externalCreateNewOrgEl = document.getElementById('open-create-org-link');
|
||||||
|
externalCreateNewOrgEl.addEventListener('click', () => {
|
||||||
|
shell.openExternal(link);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = CreateOrganziation;
|
||||||
@@ -49,10 +49,6 @@ class GeneralSection extends BaseSection {
|
|||||||
</div>
|
</div>
|
||||||
<div class="title">App Updates</div>
|
<div class="title">App Updates</div>
|
||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<div class="setting-row" id="autoupdate-option">
|
|
||||||
<div class="setting-description">Enable auto updates</div>
|
|
||||||
<div class="setting-control"></div>
|
|
||||||
</div>
|
|
||||||
<div class="setting-row" id="betaupdate-option">
|
<div class="setting-row" id="betaupdate-option">
|
||||||
<div class="setting-description">Get beta updates</div>
|
<div class="setting-description">Get beta updates</div>
|
||||||
<div class="setting-control"></div>
|
<div class="setting-control"></div>
|
||||||
@@ -108,8 +104,7 @@ class GeneralSection extends BaseSection {
|
|||||||
this.updateTrayOption();
|
this.updateTrayOption();
|
||||||
this.updateBadgeOption();
|
this.updateBadgeOption();
|
||||||
this.updateSilentOption();
|
this.updateSilentOption();
|
||||||
this.autoUpdateOption();
|
this.updateUpdateOption();
|
||||||
this.betaUpdateOption();
|
|
||||||
this.updateSidebarOption();
|
this.updateSidebarOption();
|
||||||
this.updateStartAtLoginOption();
|
this.updateStartAtLoginOption();
|
||||||
this.updateResetDataOption();
|
this.updateResetDataOption();
|
||||||
@@ -165,26 +160,14 @@ class GeneralSection extends BaseSection {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
autoUpdateOption() {
|
updateUpdateOption() {
|
||||||
this.generateSettingOption({
|
|
||||||
$element: document.querySelector('#autoupdate-option .setting-control'),
|
|
||||||
value: ConfigUtil.getConfigItem('autoUpdate', true),
|
|
||||||
clickHandler: () => {
|
|
||||||
const newValue = !ConfigUtil.getConfigItem('autoUpdate');
|
|
||||||
ConfigUtil.setConfigItem('autoUpdate', newValue);
|
|
||||||
this.autoUpdateOption();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
betaUpdateOption() {
|
|
||||||
this.generateSettingOption({
|
this.generateSettingOption({
|
||||||
$element: document.querySelector('#betaupdate-option .setting-control'),
|
$element: document.querySelector('#betaupdate-option .setting-control'),
|
||||||
value: ConfigUtil.getConfigItem('betaUpdate', false),
|
value: ConfigUtil.getConfigItem('betaUpdate', false),
|
||||||
clickHandler: () => {
|
clickHandler: () => {
|
||||||
const newValue = !ConfigUtil.getConfigItem('betaUpdate');
|
const newValue = !ConfigUtil.getConfigItem('betaUpdate');
|
||||||
ConfigUtil.setConfigItem('betaUpdate', newValue);
|
ConfigUtil.setConfigItem('betaUpdate', newValue);
|
||||||
this.betaUpdateOption();
|
this.updateUpdateOption();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -197,7 +180,7 @@ class GeneralSection extends BaseSection {
|
|||||||
const newValue = !ConfigUtil.getConfigItem('silent', true);
|
const newValue = !ConfigUtil.getConfigItem('silent', true);
|
||||||
ConfigUtil.setConfigItem('silent', newValue);
|
ConfigUtil.setConfigItem('silent', newValue);
|
||||||
this.updateSilentOption();
|
this.updateSilentOption();
|
||||||
currentBrowserWindow.send('toggle-silent', newValue);
|
currentBrowserWindow.send('toogle-silent', newValue);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class PreferenceNav extends BaseComponent {
|
|||||||
|
|
||||||
this.props = props;
|
this.props = props;
|
||||||
|
|
||||||
this.navItems = ['General', 'Network', 'AddServer', 'Organizations', 'Shortcuts'];
|
this.navItems = ['General', 'Network', 'Servers', 'Added-servers', 'Shortcuts'];
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
const BaseComponent = require(__dirname + '/../../components/base.js');
|
const BaseComponent = require(__dirname + '/../../components/base.js');
|
||||||
const DomainUtil = require(__dirname + '/../../utils/domain-util.js');
|
const DomainUtil = require(__dirname + '/../../utils/domain-util.js');
|
||||||
const shell = require('electron').shell;
|
|
||||||
|
|
||||||
class NewServerForm extends BaseComponent {
|
class NewServerForm extends BaseComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -12,24 +11,25 @@ class NewServerForm extends BaseComponent {
|
|||||||
|
|
||||||
template() {
|
template() {
|
||||||
return `
|
return `
|
||||||
<div class="server-input-container">
|
<div class="settings-card">
|
||||||
|
<div class="server-info-right">
|
||||||
<div class="title">Organization URL</div>
|
<div class="title">Organization URL</div>
|
||||||
<div class="add-server-info-row">
|
<div class="server-info-row">
|
||||||
<input class="setting-input-value" autofocus placeholder="your-organization.zulipchat.com or zulip.your-organization.com"/>
|
<input class="setting-input-value" autofocus placeholder="example.zulipchat.com or chat.example.com"/>
|
||||||
|
</div>
|
||||||
|
<div class="server-info-row">
|
||||||
|
<div class="action blue server-save-action">
|
||||||
|
<span>Next</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="server-center">
|
|
||||||
<div class="server-save-action">
|
|
||||||
<button id="connect">Connect</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="server-center">
|
|
||||||
<div class="divider">
|
<div class="divider">
|
||||||
<hr class="left"/>OR<hr class="right" />
|
<hr class="left"/>OR<hr class="right" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="server-center">
|
<div class="server-info-row">
|
||||||
<div class="server-save-action">
|
<div class="action blue server-create-action">
|
||||||
<button id="open-create-org-link">Create a new organization</button>
|
<span>Create a new organization</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -51,25 +51,17 @@ class NewServerForm extends BaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
submitFormHandler() {
|
submitFormHandler() {
|
||||||
this.$saveServerButton.children[0].innerHTML = 'Connecting...';
|
this.$saveServerButton.children[0].innerHTML = 'Adding...';
|
||||||
DomainUtil.checkDomain(this.$newServerUrl.value).then(serverConf => {
|
DomainUtil.checkDomain(this.$newServerUrl.value).then(serverConf => {
|
||||||
DomainUtil.addDomain(serverConf).then(() => {
|
DomainUtil.addDomain(serverConf).then(() => {
|
||||||
this.props.onChange(this.props.index);
|
this.props.onChange(this.props.index);
|
||||||
});
|
});
|
||||||
}, errorMessage => {
|
}, errorMessage => {
|
||||||
this.$saveServerButton.children[0].innerHTML = 'Connect';
|
this.$saveServerButton.children[0].innerHTML = 'Next';
|
||||||
alert(errorMessage);
|
alert(errorMessage);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openCreateNewOrgExternalLink() {
|
|
||||||
const link = 'https://zulipchat.com/new/';
|
|
||||||
const externalCreateNewOrgEl = document.getElementById('open-create-org-link');
|
|
||||||
externalCreateNewOrgEl.addEventListener('click', () => {
|
|
||||||
shell.openExternal(link);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
initActions() {
|
initActions() {
|
||||||
this.$saveServerButton.addEventListener('click', () => {
|
this.$saveServerButton.addEventListener('click', () => {
|
||||||
this.submitFormHandler();
|
this.submitFormHandler();
|
||||||
@@ -81,8 +73,6 @@ class NewServerForm extends BaseComponent {
|
|||||||
this.submitFormHandler();
|
this.submitFormHandler();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// open create new org link in default browser
|
|
||||||
this.openCreateNewOrgExternalLink();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ const Nav = require(__dirname + '/js/pages/preference/nav.js');
|
|||||||
const ServersSection = require(__dirname + '/js/pages/preference/servers-section.js');
|
const ServersSection = require(__dirname + '/js/pages/preference/servers-section.js');
|
||||||
const GeneralSection = require(__dirname + '/js/pages/preference/general-section.js');
|
const GeneralSection = require(__dirname + '/js/pages/preference/general-section.js');
|
||||||
const NetworkSection = require(__dirname + '/js/pages/preference/network-section.js');
|
const NetworkSection = require(__dirname + '/js/pages/preference/network-section.js');
|
||||||
const ConnectedOrgSection = require(__dirname + '/js/pages/preference/connected-org-section.js');
|
|
||||||
const ShortcutsSection = require(__dirname + '/js/pages/preference/shortcuts-section.js');
|
const ShortcutsSection = require(__dirname + '/js/pages/preference/shortcuts-section.js');
|
||||||
|
const AddedSection = require(__dirname + '/js/pages/preference/added-server-section.js');
|
||||||
|
|
||||||
class PreferenceView extends BaseComponent {
|
class PreferenceView extends BaseComponent {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -40,7 +40,7 @@ class PreferenceView extends BaseComponent {
|
|||||||
handleNavigation(navItem) {
|
handleNavigation(navItem) {
|
||||||
this.nav.select(navItem);
|
this.nav.select(navItem);
|
||||||
switch (navItem) {
|
switch (navItem) {
|
||||||
case 'AddServer': {
|
case 'Servers': {
|
||||||
this.section = new ServersSection({
|
this.section = new ServersSection({
|
||||||
$root: this.$settingsContainer
|
$root: this.$settingsContainer
|
||||||
});
|
});
|
||||||
@@ -52,14 +52,14 @@ class PreferenceView extends BaseComponent {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'Organizations': {
|
case 'Network': {
|
||||||
this.section = new ConnectedOrgSection({
|
this.section = new NetworkSection({
|
||||||
$root: this.$settingsContainer
|
$root: this.$settingsContainer
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'Network': {
|
case 'Added-servers': {
|
||||||
this.section = new NetworkSection({
|
this.section = new AddedSection({
|
||||||
$root: this.$settingsContainer
|
$root: this.$settingsContainer
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -97,15 +97,6 @@ class PreferenceView extends BaseComponent {
|
|||||||
ipcRenderer.on('toggletray', (event, state) => {
|
ipcRenderer.on('toggletray', (event, state) => {
|
||||||
this.handleToggle('tray-option', state);
|
this.handleToggle('tray-option', state);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on('toggle-dnd', (event, state, newSettings) => {
|
|
||||||
this.handleToggle('show-notification-option', newSettings.showNotification);
|
|
||||||
this.handleToggle('silent-option', newSettings.silent);
|
|
||||||
|
|
||||||
if (process.platform === 'win32') {
|
|
||||||
this.handleToggle('flash-taskbar-option', newSettings.flashTaskbarOnMessage);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,18 +16,19 @@ class ServerInfoForm extends BaseComponent {
|
|||||||
<div class="settings-card">
|
<div class="settings-card">
|
||||||
<div class="server-info-left">
|
<div class="server-info-left">
|
||||||
<img class="server-info-icon" src="${this.props.server.icon}"/>
|
<img class="server-info-icon" src="${this.props.server.icon}"/>
|
||||||
|
</div>
|
||||||
|
<div class="server-info-right">
|
||||||
<div class="server-info-row">
|
<div class="server-info-row">
|
||||||
<span class="server-info-alias">${this.props.server.alias}</span>
|
<span class="server-info-alias">${this.props.server.alias}</span>
|
||||||
<i class="material-icons open-tab-button">open_in_new</i>
|
<i class="material-icons open-tab-button">open_in_new</i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="server-info-row">
|
||||||
<div class="server-info-right">
|
<input class="setting-input-value" disabled value="${this.props.server.url}"/>
|
||||||
<div class="server-info-row server-url">
|
|
||||||
<span class="server-url-info" title="${this.props.server.url}">${this.props.server.url}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="server-info-row">
|
<div class="server-info-row">
|
||||||
<div class="action red server-delete-action">
|
<div class="action red server-delete-action">
|
||||||
<span>Disconnect</span>
|
<i class="material-icons">indeterminate_check_box</i>
|
||||||
|
<span>Delete</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,7 +44,6 @@ class ServerInfoForm extends BaseComponent {
|
|||||||
initForm() {
|
initForm() {
|
||||||
this.$serverInfoForm = this.generateNodeFromTemplate(this.template());
|
this.$serverInfoForm = this.generateNodeFromTemplate(this.template());
|
||||||
this.$serverInfoAlias = this.$serverInfoForm.getElementsByClassName('server-info-alias')[0];
|
this.$serverInfoAlias = this.$serverInfoForm.getElementsByClassName('server-info-alias')[0];
|
||||||
this.$serverIcon = this.$serverInfoForm.getElementsByClassName('server-info-icon')[0];
|
|
||||||
this.$deleteServerButton = this.$serverInfoForm.getElementsByClassName('server-delete-action')[0];
|
this.$deleteServerButton = this.$serverInfoForm.getElementsByClassName('server-delete-action')[0];
|
||||||
this.$openServerButton = this.$serverInfoForm.getElementsByClassName('open-tab-button')[0];
|
this.$openServerButton = this.$serverInfoForm.getElementsByClassName('open-tab-button')[0];
|
||||||
this.props.$root.appendChild(this.$serverInfoForm);
|
this.props.$root.appendChild(this.$serverInfoForm);
|
||||||
@@ -71,12 +71,7 @@ class ServerInfoForm extends BaseComponent {
|
|||||||
this.$serverInfoAlias.addEventListener('click', () => {
|
this.$serverInfoAlias.addEventListener('click', () => {
|
||||||
ipcRenderer.send('forward-message', 'switch-server-tab', this.props.index);
|
ipcRenderer.send('forward-message', 'switch-server-tab', this.props.index);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$serverIcon.addEventListener('click', () => {
|
|
||||||
ipcRenderer.send('forward-message', 'switch-server-tab', this.props.index);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ServerInfoForm;
|
module.exports = ServerInfoForm;
|
||||||
|
|||||||
@@ -11,12 +11,14 @@ class ServersSection extends BaseSection {
|
|||||||
|
|
||||||
template() {
|
template() {
|
||||||
return `
|
return `
|
||||||
<div class="add-server-modal">
|
<div id="myModal" class="modal">
|
||||||
<div class="modal-container">
|
<div class="modal-content">
|
||||||
|
|
||||||
<div class="settings-pane" id="server-settings-pane">
|
<div class="settings-pane" id="server-settings-pane">
|
||||||
<div class="page-title">Add a Zulip organization</div>
|
<div class="page-title">Add a Zulip organization</div>
|
||||||
<div id="new-server-container"></div>
|
<div id="new-server-container"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -30,9 +32,16 @@ class ServersSection extends BaseSection {
|
|||||||
this.props.$root.innerHTML = '';
|
this.props.$root.innerHTML = '';
|
||||||
|
|
||||||
this.props.$root.innerHTML = this.template();
|
this.props.$root.innerHTML = this.template();
|
||||||
|
this.$serverInfoContainer = document.getElementById('server-info-container');
|
||||||
|
this.$existingServers = document.getElementById('existing-servers');
|
||||||
this.$newServerContainer = document.getElementById('new-server-container');
|
this.$newServerContainer = document.getElementById('new-server-container');
|
||||||
|
this.$newServerButton = document.getElementById('new-server-action');
|
||||||
|
|
||||||
this.initNewServerForm();
|
this.initNewServerForm();
|
||||||
|
|
||||||
|
this.$createOrganizationContainer = document.getElementById('create-organization-container');
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initNewServerForm() {
|
initNewServerForm() {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const BaseSection = require(__dirname + '/base-section.js');
|
const BaseSection = require(__dirname + '/base-section.js');
|
||||||
const shell = require('electron').shell;
|
|
||||||
|
|
||||||
class ShortcutsSection extends BaseSection {
|
class ShortcutsSection extends BaseSection {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -24,10 +23,6 @@ class ShortcutsSection extends BaseSection {
|
|||||||
<tr>
|
<tr>
|
||||||
<td><kbd>${userOSKey}</kbd><kbd>K</kbd></td>
|
<td><kbd>${userOSKey}</kbd><kbd>K</kbd></td>
|
||||||
<td>Keyboard Shortcuts</td>
|
<td>Keyboard Shortcuts</td>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><kbd>${userOSKey}</kbd> + <kbd>Shift</kbd> + <kbd>M</kbd></td>
|
|
||||||
<td>Toggle Do Not Disturb</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><kbd>Shift</kbd><kbd>${userOSKey}</kbd><kbd>D</kbd></td>
|
<td><kbd>Shift</kbd><kbd>${userOSKey}</kbd><kbd>D</kbd></td>
|
||||||
@@ -83,6 +78,14 @@ class ShortcutsSection extends BaseSection {
|
|||||||
<td><kbd>${userOSKey}</kbd><kbd>A</kbd></td>
|
<td><kbd>${userOSKey}</kbd><kbd>A</kbd></td>
|
||||||
<td>Select All</td>
|
<td>Select All</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><kbd>${userOSKey}</kbd><kbd>F</kbd></td>
|
||||||
|
<td>Find</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><kbd>${userOSKey}</kbd><kbd>G</kbd></td>
|
||||||
|
<td>Find Next</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><kbd>Control</kbd><kbd>${userOSKey}</kbd><kbd>Space</kbd></td>
|
<td><kbd>Control</kbd><kbd>${userOSKey}</kbd><kbd>Space</kbd></td>
|
||||||
<td>Emoji & Symbols</td>
|
<td>Emoji & Symbols</td>
|
||||||
@@ -118,7 +121,7 @@ class ShortcutsSection extends BaseSection {
|
|||||||
<td>Actual Size</td>
|
<td>Actual Size</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><kbd>${userOSKey}</kbd> + <kbd>Shift</kbd> + <kbd>S</kbd></td>
|
<td><kbd>${userOSKey}</kbd><kbd>S</kbd></td>
|
||||||
<td>Toggle Sidebar</td>
|
<td>Toggle Sidebar</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -160,7 +163,6 @@ class ShortcutsSection extends BaseSection {
|
|||||||
</table>
|
</table>
|
||||||
<div class="setting-control"></div>
|
<div class="setting-control"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-card tip"><b><i class="material-icons md-14">settings</i>Tip: </b>These desktop app shortcuts extend the Zulip webapp's <span id="open-hotkeys-link">keyboard shortcuts</span>.</div>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -180,10 +182,6 @@ class ShortcutsSection extends BaseSection {
|
|||||||
<tr>
|
<tr>
|
||||||
<td><kbd>${userOSKey}</kbd> + <kbd>K</kbd></td>
|
<td><kbd>${userOSKey}</kbd> + <kbd>K</kbd></td>
|
||||||
<td>Keyboard Shortcuts</td>
|
<td>Keyboard Shortcuts</td>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><kbd>${userOSKey}</kbd> + <kbd>Shift</kbd> + <kbd>M</kbd></td>
|
|
||||||
<td>Toggle Do Not Disturb</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><kbd>${userOSKey}</kbd> + <kbd>L</kbd></td>
|
<td><kbd>${userOSKey}</kbd> + <kbd>L</kbd></td>
|
||||||
@@ -258,7 +256,7 @@ class ShortcutsSection extends BaseSection {
|
|||||||
<td>Actual Size</td>
|
<td>Actual Size</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><kbd>${userOSKey}</kbd> + <kbd>Shift</kbd> + <kbd>S</kbd></td>
|
<td><kbd>${userOSKey}</kbd> + <kbd>S</kbd></td>
|
||||||
<td>Toggle Sidebar</td>
|
<td>Toggle Sidebar</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -300,22 +298,13 @@ class ShortcutsSection extends BaseSection {
|
|||||||
</table>
|
</table>
|
||||||
<div class="setting-control"></div>
|
<div class="setting-control"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tip"><b><i class="material-icons md-14">lightbulb_outline</i>Tip: </b>These desktop app shortcuts extend the Zulip webapp's <span id="open-hotkeys-link">keyboard shortcuts</span>.</div>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
openHotkeysExternalLink() {
|
|
||||||
const link = 'https://zulipchat.com/help/keyboard-shortcuts';
|
|
||||||
const externalCreateNewOrgEl = document.getElementById('open-hotkeys-link');
|
|
||||||
externalCreateNewOrgEl.addEventListener('click', () => {
|
|
||||||
shell.openExternal(link);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
init() {
|
init() {
|
||||||
this.props.$root.innerHTML = (process.platform === 'darwin') ?
|
this.props.$root.innerHTML = (process.platform === 'darwin') ?
|
||||||
this.templateMac() : this.templateWinLin();
|
this.templateMac() : this.templateWinLin();
|
||||||
this.openHotkeysExternalLink();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,14 +4,10 @@ const { ipcRenderer } = require('electron');
|
|||||||
const SetupSpellChecker = require('./spellchecker');
|
const SetupSpellChecker = require('./spellchecker');
|
||||||
|
|
||||||
const ConfigUtil = require(__dirname + '/utils/config-util.js');
|
const ConfigUtil = require(__dirname + '/utils/config-util.js');
|
||||||
const LinkUtil = require(__dirname + '/utils/link-util.js');
|
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-unassigned-import
|
// eslint-disable-next-line import/no-unassigned-import
|
||||||
require('./notification');
|
require('./notification');
|
||||||
|
|
||||||
// Prevent drag and drop event in main process which prevents remote code executaion
|
|
||||||
require(__dirname + '/shared/preventdrag.js');
|
|
||||||
|
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
// Create the menu for the below
|
// Create the menu for the below
|
||||||
document.querySelector('.dropdown-toggle').click();
|
document.querySelector('.dropdown-toggle').click();
|
||||||
@@ -24,7 +20,7 @@ const shortcut = () => {
|
|||||||
// Create the menu for the below
|
// Create the menu for the below
|
||||||
const node = document.querySelector('a[data-overlay-trigger=keyboard-shortcuts]');
|
const node = document.querySelector('a[data-overlay-trigger=keyboard-shortcuts]');
|
||||||
// Additional check
|
// Additional check
|
||||||
if (node.text.trim().toLowerCase() === 'keyboard shortcuts (?)') {
|
if (node.text.trim().toLowerCase() === 'keyboard shortcuts') {
|
||||||
node.click();
|
node.click();
|
||||||
} else {
|
} else {
|
||||||
// Atleast click the dropdown
|
// Atleast click the dropdown
|
||||||
@@ -56,24 +52,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
ipcRenderer.send('forward-message', 'reload-viewer');
|
ipcRenderer.send('forward-message', 'reload-viewer');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open image attachment link in the lightbox instead of opening in the default browser
|
|
||||||
const { $, lightbox } = window;
|
|
||||||
|
|
||||||
$('#main_div').on('click', '.message_content p a', function (e) {
|
|
||||||
const url = $(this).attr('href');
|
|
||||||
|
|
||||||
if (LinkUtil.isImage(url)) {
|
|
||||||
const $img = $(this).parent().siblings('.message_inline_image').find('img');
|
|
||||||
|
|
||||||
// prevent the image link from opening in a new page.
|
|
||||||
e.preventDefault();
|
|
||||||
// prevent the message compose dialog from happening.
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
lightbox.open($img);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Clean up spellchecker events after you navigate away from this page;
|
// Clean up spellchecker events after you navigate away from this page;
|
||||||
@@ -82,10 +60,3 @@ window.addEventListener('beforeunload', () => {
|
|||||||
SetupSpellChecker.unsubscribeSpellChecker();
|
SetupSpellChecker.unsubscribeSpellChecker();
|
||||||
});
|
});
|
||||||
|
|
||||||
// electron's globalShortcut can cause unexpected results
|
|
||||||
// so adding the reload shortcut in the old-school way
|
|
||||||
document.addEventListener('keydown', event => {
|
|
||||||
if (event.code === 'F5') {
|
|
||||||
ipcRenderer.send('forward-message', 'hard-reload');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
// This is a security fix. Following function prevents drag and drop event in the app
|
|
||||||
// so that attackers can't execute any remote code within the app
|
|
||||||
// It doesn't affect the compose box so that users can still
|
|
||||||
// use drag and drop event to share files etc
|
|
||||||
|
|
||||||
const preventDragAndDrop = () => {
|
|
||||||
const preventEvents = ['dragover', 'drop'];
|
|
||||||
preventEvents.forEach(dragEvents => {
|
|
||||||
document.addEventListener(dragEvents, event => {
|
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
preventDragAndDrop();
|
|
||||||
@@ -98,7 +98,7 @@ const renderNativeImage = function (arg) {
|
|||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
.then(() => renderCanvas(arg))
|
.then(() => renderCanvas(arg))
|
||||||
.then(canvas => {
|
.then(canvas => {
|
||||||
const pngData = nativeImage.createFromDataURL(canvas.toDataURL('image/png')).toPNG();
|
const pngData = nativeImage.createFromDataURL(canvas.toDataURL('image/png')).toPng();
|
||||||
return Promise.resolve(nativeImage.createFromBuffer(pngData, config.pixelRatio));
|
return Promise.resolve(nativeImage.createFromBuffer(pngData, config.pixelRatio));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const ConfigUtil = require(__dirname + '/config-util.js');
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
const dnd = !ConfigUtil.getConfigItem('dnd', false);
|
|
||||||
const dndSettingList = ['showNotification', 'silent'];
|
|
||||||
if (process.platform === 'win32') {
|
|
||||||
dndSettingList.push('flashTaskbarOnMessage');
|
|
||||||
}
|
|
||||||
|
|
||||||
let newSettings;
|
|
||||||
if (dnd) {
|
|
||||||
const oldSettings = {};
|
|
||||||
newSettings = {};
|
|
||||||
|
|
||||||
// Iterate through the dndSettingList.
|
|
||||||
for (const settingName of dndSettingList) {
|
|
||||||
// Store the current value of setting.
|
|
||||||
oldSettings[settingName] = ConfigUtil.getConfigItem(settingName);
|
|
||||||
// New value of setting.
|
|
||||||
newSettings[settingName] = (settingName === 'silent');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store old value in oldSettings.
|
|
||||||
ConfigUtil.setConfigItem('dndPreviousSettings', oldSettings);
|
|
||||||
} else {
|
|
||||||
newSettings = ConfigUtil.getConfigItem('dndPreviousSettings');
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const settingName of dndSettingList) {
|
|
||||||
ConfigUtil.setConfigItem(settingName, newSettings[settingName]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigUtil.setConfigItem('dnd', dnd);
|
|
||||||
return {dnd, newSettings};
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
toggle
|
|
||||||
};
|
|
||||||
@@ -5,8 +5,6 @@ const fs = require('fs');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const JsonDB = require('node-json-db');
|
const JsonDB = require('node-json-db');
|
||||||
const request = require('request');
|
const request = require('request');
|
||||||
const escape = require('escape-html');
|
|
||||||
|
|
||||||
const Logger = require('./logger-util');
|
const Logger = require('./logger-util');
|
||||||
|
|
||||||
const logger = new Logger({
|
const logger = new Logger({
|
||||||
@@ -190,7 +188,7 @@ class DomainUtil {
|
|||||||
// Following check handles both the cases
|
// Following check handles both the cases
|
||||||
icon: data.realm_icon.startsWith('/') ? data.realm_uri + data.realm_icon : data.realm_icon,
|
icon: data.realm_icon.startsWith('/') ? data.realm_uri + data.realm_icon : data.realm_icon,
|
||||||
url: data.realm_uri,
|
url: data.realm_uri,
|
||||||
alias: escape(data.realm_name)
|
alias: data.realm_name
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -19,20 +19,7 @@ class LinkUtil {
|
|||||||
const currentDomain = wurl('hostname', currentUrl);
|
const currentDomain = wurl('hostname', currentUrl);
|
||||||
const newDomain = wurl('hostname', newUrl);
|
const newDomain = wurl('hostname', newUrl);
|
||||||
|
|
||||||
const sameDomainUrl = (currentDomain === newDomain || newUrl === currentUrl + '/');
|
return (currentDomain === newDomain) && newUrl.includes('/#narrow');
|
||||||
const isUploadsUrl = newUrl.includes(currentUrl + '/user_uploads/');
|
|
||||||
const isInternalUrl = newUrl.includes('/#narrow') || isUploadsUrl;
|
|
||||||
|
|
||||||
return {
|
|
||||||
isInternalUrl: sameDomainUrl && isInternalUrl,
|
|
||||||
isUploadsUrl
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
isImage(url) {
|
|
||||||
// test for images extension as well as urls like .png?s=100
|
|
||||||
const isImageUrl = /\.(bmp|gif|jpg|jpeg|png|webp)\?*.*$/i;
|
|
||||||
return isImageUrl.test(url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,11 +37,9 @@ class ReconnectUtil {
|
|||||||
|
|
||||||
console.log('There is no internet connection, try checking network cables, modem and router.');
|
console.log('There is no internet connection, try checking network cables, modem and router.');
|
||||||
const errMsgHolder = document.querySelector('#description');
|
const errMsgHolder = document.querySelector('#description');
|
||||||
if (errMsgHolder) {
|
|
||||||
errMsgHolder.innerHTML = `
|
errMsgHolder.innerHTML = `
|
||||||
<div>You internet connection does't seem to work properly!</div>
|
<div>You internet connection does't seem to work properly!</div>
|
||||||
</div>Verify that it works and then click try again.</div>`;
|
</div>Verify that it works and then click try again.</div>`;
|
||||||
}
|
|
||||||
return resolve(false);
|
return resolve(false);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -24,10 +24,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="actions-container">
|
<div id="actions-container">
|
||||||
<div class="action-button" id="dnd-action">
|
|
||||||
<i class="material-icons md-48">notifications</i>
|
|
||||||
<span id="dnd-tooltip" style="display:none">Do Not Disturb</span>
|
|
||||||
</div>
|
|
||||||
<div class="action-button" id="reload-action">
|
<div class="action-button" id="reload-action">
|
||||||
<i class="material-icons md-48">refresh</i>
|
<i class="material-icons md-48">refresh</i>
|
||||||
<span id="reload-tooltip" style="display:none">Reload</span>
|
<span id="reload-tooltip" style="display:none">Reload</span>
|
||||||
@@ -46,11 +42,6 @@
|
|||||||
<div id="webviews-container"></div>
|
<div id="webviews-container"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="feedback-modal">
|
|
||||||
<send-feedback></send-feedback>
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
<script src="js/main.js"></script>
|
<script src="js/main.js"></script>
|
||||||
<script>require('./js/shared/preventdrag.js')</script>
|
|
||||||
</html>
|
</html>
|
||||||
@@ -18,5 +18,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script src="js/pages/network.js"></script>
|
<script src="js/pages/network.js"></script>
|
||||||
<script>require('./js/shared/preventdrag.js')</script>
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,11 +1,157 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" class="responsive desktop">
|
<html lang="en" class="responsive desktop">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width">
|
||||||
<title>Zulip - Settings</title>
|
<title>Zulip - Settings</title>
|
||||||
<link rel="stylesheet" href="css/preference.css" type="text/css" media="screen">
|
<link rel="stylesheet" href="css/preference.css" type="text/css" media="screen">
|
||||||
|
<style>
|
||||||
|
/* The Modal (background) */
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
display: block;
|
||||||
|
/* Hidden by default */
|
||||||
|
position: fixed;
|
||||||
|
/* Stay in place */
|
||||||
|
z-index: 1;
|
||||||
|
/* Sit on top */
|
||||||
|
padding-top: 100px;
|
||||||
|
/* Location of the box */
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
/* Full width */
|
||||||
|
height: 100%;
|
||||||
|
/* Full height */
|
||||||
|
overflow: auto;
|
||||||
|
/* Enable scroll if needed */
|
||||||
|
/* background-color: rgb(0, 0, 0); */
|
||||||
|
/* Fallback color */
|
||||||
|
/* background-color: rgba(0, 0, 0, 0.4); */
|
||||||
|
background: rgba(61, 64, 67, 15);
|
||||||
|
/* Black w/ opacity */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modal Content */
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background-color: #fefefe;
|
||||||
|
margin: auto;
|
||||||
|
padding: 57px;
|
||||||
|
border: #dae1e3 1px solid;
|
||||||
|
width: 600px;
|
||||||
|
/* margin-bottom: 113px; */
|
||||||
|
height: 344px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The Close Button */
|
||||||
|
|
||||||
|
.close {
|
||||||
|
color: #aaaaaa;
|
||||||
|
float: right;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close:hover,
|
||||||
|
.close:focus {
|
||||||
|
color: #000;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#server-settings-pane {
|
||||||
|
margin-left: 18%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-card.server-info-right:hover {
|
||||||
|
box-shadow: none !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.server-save-action {
|
||||||
|
padding: 11px;
|
||||||
|
padding-left: 20px;
|
||||||
|
width: 292px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 16px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
/* width: 250px;
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 39px;
|
||||||
|
margin-top: 48px; */
|
||||||
|
|
||||||
|
width: 335px;
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 0px;
|
||||||
|
margin-top: 48px;
|
||||||
|
color: #7d878a;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider hr {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 42%;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.server-create-action {
|
||||||
|
width: 314px;
|
||||||
|
margin-top: 40px;
|
||||||
|
padding: 11px;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.server-create-action span {
|
||||||
|
margin-left: 60px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.server-save-action span {
|
||||||
|
margin-left: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.server-save-action {
|
||||||
|
width: 306px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.server-info-row {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-input-value {
|
||||||
|
width: 319px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
color: #222c31;
|
||||||
|
margin-left: 65px;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 100;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
color: #7d878a;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<div id="sidebar"></div>
|
<div id="sidebar"></div>
|
||||||
@@ -13,5 +159,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script src="js/pages/preference/preference.js"></script>
|
<script src="js/pages/preference/preference.js"></script>
|
||||||
<script>require('./js/shared/preventdrag.js')</script>
|
|
||||||
</html>
|
</html>
|
||||||
@@ -8,7 +8,7 @@ cache:
|
|||||||
- node_modules
|
- node_modules
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- ps: Install-Product node 8 x64
|
- ps: Install-Product node 6 x64
|
||||||
- git reset --hard HEAD
|
- git reset --hard HEAD
|
||||||
- npm install npm -g
|
- npm install npm -g
|
||||||
- node --version
|
- node --version
|
||||||
@@ -21,4 +21,4 @@ build: off
|
|||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- npm run test
|
- npm run test
|
||||||
# - npm run test-e2e
|
- npm run test-e2e
|
||||||
|
|||||||
BIN
build/appdmg.png
BIN
build/appdmg.png
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 6.2 KiB |
@@ -15,7 +15,6 @@ To build and run the app from source, you'll need the following:
|
|||||||
* [Python](https://www.python.org/downloads/release/python-2713/)
|
* [Python](https://www.python.org/downloads/release/python-2713/)
|
||||||
(v2.7.x recommended)
|
(v2.7.x recommended)
|
||||||
* A C++ compiler compatible with C++11
|
* A C++ compiler compatible with C++11
|
||||||
* Linux users also need [Snapcraft](https://snapcraft.io/)
|
|
||||||
* Development headers for the libXext, libXtst, and libxkbfile libraries
|
* Development headers for the libXext, libXtst, and libxkbfile libraries
|
||||||
|
|
||||||
### Debian/Ubuntu and friends
|
### Debian/Ubuntu and friends
|
||||||
@@ -26,7 +25,7 @@ manager (see [here][nodesource-install] for more on the first command):
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
|
$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
|
||||||
$ sudo apt install git nodejs python build-essential snapcraft libxext-dev libxtst-dev libxkbfile-dev libgconf-2-4
|
$ sudo apt install git nodejs python build-essential libxext-dev libxtst-dev libxkbfile-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
[nodesource-install]: https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions
|
[nodesource-install]: https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions
|
||||||
@@ -77,7 +76,7 @@ This command will produce distributable packages or installers for the
|
|||||||
operating system you're running on:
|
operating system you're running on:
|
||||||
* on Windows, a Windows installer file
|
* on Windows, a Windows installer file
|
||||||
* on macOS, a `.dmg` file
|
* on macOS, a `.dmg` file
|
||||||
* on Linux, a plain `.zip` file as well as a `.deb` file, `.snap` file and an
|
* on Linux, a plain `.zip` file as well as a `.deb` file and an
|
||||||
`AppImage` file.
|
`AppImage` file.
|
||||||
To generate all three types, you will need all three operating
|
To generate all three types, you will need all three operating
|
||||||
systems.
|
systems.
|
||||||
|
|||||||
8202
package-lock.json
generated
8202
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
38
package.json
38
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "zulip",
|
"name": "zulip",
|
||||||
"productName": "Zulip",
|
"productName": "Zulip",
|
||||||
"version": "2.3.1",
|
"version": "1.8.2",
|
||||||
"main": "./app/main",
|
"main": "./app/main",
|
||||||
"description": "Zulip Desktop App",
|
"description": "Zulip Desktop App",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "electron app --disable-http-cache --no-electron-connect",
|
"start": "electron app --disable-http-cache --no-electron-connect",
|
||||||
"reinstall": "node ./tools/reinstall-node-modules.js",
|
"reinstall": "./tools/reinstall-node-modules",
|
||||||
"postinstall": "electron-builder install-app-deps",
|
"postinstall": "electron-builder install-app-deps",
|
||||||
"test": "xo",
|
"test": "xo",
|
||||||
"test-e2e": "gulp test-e2e",
|
"test-e2e": "gulp test-e2e",
|
||||||
@@ -46,8 +46,7 @@
|
|||||||
],
|
],
|
||||||
"copyright": "©2017 Kandra Labs, Inc.",
|
"copyright": "©2017 Kandra Labs, Inc.",
|
||||||
"mac": {
|
"mac": {
|
||||||
"category": "public.app-category.productivity",
|
"category": "public.app-category.productivity"
|
||||||
"artifactName": "${productName}-${version}-${arch}.${ext}"
|
|
||||||
},
|
},
|
||||||
"linux": {
|
"linux": {
|
||||||
"category": "Chat;GNOME;GTK;Network;InstantMessaging",
|
"category": "Chat;GNOME;GTK;Network;InstantMessaging",
|
||||||
@@ -56,41 +55,32 @@
|
|||||||
"target": [
|
"target": [
|
||||||
"deb",
|
"deb",
|
||||||
"zip",
|
"zip",
|
||||||
"AppImage",
|
"AppImage"
|
||||||
"snap"
|
|
||||||
],
|
],
|
||||||
"maintainer": "Akash Nimare <svnitakash@gmail.com>",
|
"maintainer": "Akash Nimare <svnitakash@gmail.com>"
|
||||||
"artifactName": "${productName}-${version}-${arch}.${ext}"
|
|
||||||
},
|
},
|
||||||
"deb": {
|
"deb": {
|
||||||
"synopsis": "Zulip Desktop App",
|
"synopsis": "Zulip Desktop App",
|
||||||
"afterInstall": "./scripts/debian-add-repo.sh",
|
"afterInstall": "./scripts/debian-add-repo.sh",
|
||||||
"afterRemove": "./scripts/debian-uninstaller.sh"
|
"afterRemove": "./scripts/debian-uninstaller.sh"
|
||||||
},
|
},
|
||||||
"snap": {
|
|
||||||
"synopsis": "Zulip Desktop App"
|
|
||||||
},
|
|
||||||
"dmg": {
|
"dmg": {
|
||||||
"background": "build/appdmg.png",
|
"background": "build/appdmg.png",
|
||||||
"icon": "build/icon.icns",
|
"icon": "build/icon.icns",
|
||||||
"iconSize": 100,
|
"iconSize": 128,
|
||||||
"contents": [
|
"contents": [
|
||||||
{
|
{
|
||||||
"x": 380,
|
"x": 380,
|
||||||
"y": 280,
|
"y": 240,
|
||||||
"type": "link",
|
"type": "link",
|
||||||
"path": "/Applications"
|
"path": "/Applications"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"x": 110,
|
"x": 122,
|
||||||
"y": 280,
|
"y": 240,
|
||||||
"type": "file"
|
"type": "file"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"window": {
|
|
||||||
"width": 500,
|
|
||||||
"height": 500
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"win": {
|
"win": {
|
||||||
"target": [
|
"target": [
|
||||||
@@ -123,17 +113,17 @@
|
|||||||
"assert": "1.4.1",
|
"assert": "1.4.1",
|
||||||
"cp-file": "^5.0.0",
|
"cp-file": "^5.0.0",
|
||||||
"devtron": "1.4.0",
|
"devtron": "1.4.0",
|
||||||
"electron": "2.0.1",
|
"electron": "1.8.2",
|
||||||
"electron-builder": "20.13.4",
|
"electron-builder": "19.53.6",
|
||||||
"electron-connect": "0.6.2",
|
"electron-connect": "0.6.2",
|
||||||
"electron-debug": "1.4.0",
|
"electron-debug": "1.4.0",
|
||||||
"google-translate-api": "2.3.0",
|
"google-translate-api": "2.3.0",
|
||||||
"gulp": "^4.0.0",
|
"gulp": "3.9.1",
|
||||||
"gulp-tape": "0.0.9",
|
"gulp-tape": "0.0.9",
|
||||||
"is-ci": "^1.0.10",
|
"is-ci": "^1.0.10",
|
||||||
"nodemon": "^1.14.11",
|
"nodemon": "^1.14.11",
|
||||||
"pre-commit": "1.2.2",
|
"pre-commit": "1.2.2",
|
||||||
"spectron": "3.8.0",
|
"spectron": "3.7.2",
|
||||||
"tap-colorize": "^1.2.0",
|
"tap-colorize": "^1.2.0",
|
||||||
"tape": "^4.8.0",
|
"tape": "^4.8.0",
|
||||||
"xo": "0.18.2"
|
"xo": "0.18.2"
|
||||||
|
|||||||
@@ -2,10 +2,6 @@
|
|||||||
|
|
||||||
# This script runs when user install the debian package
|
# This script runs when user install the debian package
|
||||||
|
|
||||||
# Link to the binary
|
|
||||||
ln -sf '/opt/${productFilename}/${executable}' '/usr/local/bin/${executable}';
|
|
||||||
echo 'Successfully added /opt/${productFilename}/${executable} to /usr/local/bin/${executable}'
|
|
||||||
|
|
||||||
# Install apt repository source list if it does not exist
|
# Install apt repository source list if it does not exist
|
||||||
if ! grep ^ /etc/apt/sources.list /etc/apt/sources.list.d/* | grep zulip.list; then
|
if ! grep ^ /etc/apt/sources.list /etc/apt/sources.list.d/* | grep zulip.list; then
|
||||||
sudo apt-key adv --keyserver pool.sks-keyservers.net --recv 69AD12704E71A4803DCA3A682424BE5AE9BD10D9
|
sudo apt-key adv --keyserver pool.sks-keyservers.net --recv 69AD12704E71A4803DCA3A682424BE5AE9BD10D9
|
||||||
|
|||||||
@@ -29,7 +29,3 @@ appDirectory=/home/$getSudoUser/.config/Zulip/;
|
|||||||
if [ -d $appDirectory ]; then
|
if [ -d $appDirectory ]; then
|
||||||
sudo rm -rf $appDirectory;
|
sudo rm -rf $appDirectory;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Delete the link to the binary
|
|
||||||
echo 'Removing binary link'
|
|
||||||
sudo rm -f '/usr/local/bin/${executable}';
|
|
||||||
@@ -15,6 +15,6 @@ fi
|
|||||||
|
|
||||||
npm run test
|
npm run test
|
||||||
|
|
||||||
# if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||||
# npm run test-e2e
|
npm run test-e2e
|
||||||
# fi
|
fi
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -1,37 +0,0 @@
|
|||||||
name: zulip
|
|
||||||
version: 2.0.0
|
|
||||||
summary: Zulip Desktop Client for Linux
|
|
||||||
description: Zulip combines the immediacy of Slack with an email threading model. With Zulip, you can catch up on important conversations while ignoring irrelevant ones.
|
|
||||||
confinement: strict
|
|
||||||
grade: stable
|
|
||||||
icon: snap/gui/icon.png
|
|
||||||
apps:
|
|
||||||
zulip:
|
|
||||||
command: env TMPDIR=$XDG_RUNTIME_DIR desktop-launch $SNAP/zulip
|
|
||||||
plugs:
|
|
||||||
- desktop
|
|
||||||
- desktop-legacy
|
|
||||||
- home
|
|
||||||
- x11
|
|
||||||
- unity7
|
|
||||||
- browser-support
|
|
||||||
- network
|
|
||||||
- gsettings
|
|
||||||
- pulseaudio
|
|
||||||
- opengl
|
|
||||||
parts:
|
|
||||||
app:
|
|
||||||
plugin: dump
|
|
||||||
stage-packages:
|
|
||||||
- libasound2
|
|
||||||
- libgconf2-4
|
|
||||||
- libnotify4
|
|
||||||
- libnspr4
|
|
||||||
- libnss3
|
|
||||||
- libpcre3
|
|
||||||
- libpulse0
|
|
||||||
- libxss1
|
|
||||||
- libxtst6
|
|
||||||
source: dist/linux-unpacked
|
|
||||||
after:
|
|
||||||
- desktop-gtk2
|
|
||||||
@@ -7,7 +7,7 @@ test('app runs', function (t) {
|
|||||||
const app = setup.createApp()
|
const app = setup.createApp()
|
||||||
setup.waitForLoad(app, t)
|
setup.waitForLoad(app, t)
|
||||||
.then(() => app.client.windowByIndex(1)) // focus on webview
|
.then(() => app.client.windowByIndex(1)) // focus on webview
|
||||||
.then(() => app.client.waitForExist('//*[@id="connect"]')) // id of the connect button
|
.then(() => app.client.waitForExist('//*[@id="new-server-container"]/div/div/div[2]/input'))
|
||||||
.then(() => setup.endTest(app, t),
|
.then(() => setup.endTest(app, t),
|
||||||
(err) => setup.endTest(app, t, err || 'error'))
|
(err) => setup.endTest(app, t, err || 'error'))
|
||||||
})
|
})
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
const test = require('tape')
|
|
||||||
const setup = require('./setup')
|
|
||||||
|
|
||||||
// Create new org link should open in the default browser [WIP]
|
|
||||||
|
|
||||||
test('new-org-link', function (t) {
|
|
||||||
t.timeoutAfter(50e3)
|
|
||||||
setup.resetTestDataDir()
|
|
||||||
const app = setup.createApp()
|
|
||||||
setup.waitForLoad(app, t)
|
|
||||||
.then(() => app.client.windowByIndex(1)) // focus on webview
|
|
||||||
.then(() => app.client.click('#open-create-org-link')) // Click on new org link button
|
|
||||||
.then(() => setup.wait(5000))
|
|
||||||
.then(() => setup.endTest(app, t),
|
|
||||||
(err) => setup.endTest(app, t, err || 'error'))
|
|
||||||
})
|
|
||||||
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
const {exec} = require('child_process');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const isWindows = process.platform === 'win32';
|
|
||||||
const command = path.join(__dirname, `reinstall-node-modules${isWindows ? '.cmd' : ''}`);
|
|
||||||
|
|
||||||
const proc = exec(command, error => {
|
|
||||||
if (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
proc.stdout.on('data', data => console.log(data.toString()));
|
|
||||||
proc.stderr.on('data', data => console.error(data.toString()));
|
|
||||||
proc.on('exit', code => {
|
|
||||||
process.exit(code);
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user