mirror of
				https://github.com/zulip/zulip-desktop.git
				synced 2025-11-04 05:53:21 +00:00 
			
		
		
		
	Finish the framework of settings.
This commit is contained in:
		@@ -5,7 +5,35 @@ body {
 | 
			
		||||
    cursor: default;
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    color: #333;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
    background: #efefef;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@font-face {
 | 
			
		||||
  font-family: 'Material Icons';
 | 
			
		||||
  font-style: normal;
 | 
			
		||||
  font-weight: 400;
 | 
			
		||||
  src: local('Material Icons'),
 | 
			
		||||
       local('MaterialIcons-Regular'),
 | 
			
		||||
       url(../fonts/MaterialIcons-Regular.ttf) format('truetype');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.material-icons {
 | 
			
		||||
  font-family: 'Material Icons';
 | 
			
		||||
  font-weight: normal;
 | 
			
		||||
  font-style: normal;
 | 
			
		||||
  /* Preferred icon size */
 | 
			
		||||
  font-size: 24px;
 | 
			
		||||
  display: inline-block;
 | 
			
		||||
  line-height: 1;
 | 
			
		||||
  text-transform: none;
 | 
			
		||||
  letter-spacing: normal;
 | 
			
		||||
  word-wrap: normal;
 | 
			
		||||
  white-space: nowrap;
 | 
			
		||||
  direction: ltr;
 | 
			
		||||
  /* Support for all WebKit browsers. */
 | 
			
		||||
  -webkit-font-smoothing: antialiased;
 | 
			
		||||
  /* Support for Safari and Chrome. */
 | 
			
		||||
  text-rendering: optimizeLegibility;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#content {
 | 
			
		||||
@@ -59,14 +87,26 @@ body {
 | 
			
		||||
    overflow-y: scroll;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.server-info-container {
 | 
			
		||||
#server-info-container {
 | 
			
		||||
    margin: 20px 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#new-server-container {
 | 
			
		||||
    margin: 20px 0;
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
    transition: opacity 0.3s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.title {
 | 
			
		||||
    padding: 4px 0 6px 0;
 | 
			
		||||
    font-size: 18px;
 | 
			
		||||
    color: #000;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    color: #1e1e1e;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sub-title {
 | 
			
		||||
    padding: 4px 0 6px 0;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    color: #616161;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
img.server-info-icon {
 | 
			
		||||
@@ -78,22 +118,25 @@ img.server-info-icon {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.server-info-left {
 | 
			
		||||
    margin-right: 20px;
 | 
			
		||||
    margin: 10px 20px 0 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.server-info-right {
 | 
			
		||||
    flex-grow: 1;
 | 
			
		||||
    margin-right: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.server-info-row {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    line-height: 26px;
 | 
			
		||||
    height: 40px;
 | 
			
		||||
    line-height: 27px;
 | 
			
		||||
    margin: 8px 0;
 | 
			
		||||
    height: 27px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.server-info-key {
 | 
			
		||||
    width: 40px;
 | 
			
		||||
    margin-right: 20px;
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
    text-align: right;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -102,14 +145,14 @@ img.server-info-icon {
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
    height: 24px;
 | 
			
		||||
    border: none;
 | 
			
		||||
    border-bottom: #ddd 1px solid;
 | 
			
		||||
    border-bottom: #ededed 1px solid;
 | 
			
		||||
    outline-width: 0;
 | 
			
		||||
    background: transparent;
 | 
			
		||||
    max-width: 500px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.server-info-value:focus {
 | 
			
		||||
    border-bottom: #b0d8ce 2px solid;
 | 
			
		||||
    border-bottom: #388E3C 1px solid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.actions-container {
 | 
			
		||||
@@ -124,12 +167,14 @@ img.server-info-icon {
 | 
			
		||||
.action {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    margin-right: 20px;
 | 
			
		||||
    padding: 0 10px;
 | 
			
		||||
    border-radius: 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.action i {
 | 
			
		||||
    margin-right: 5px;
 | 
			
		||||
    font-size: 18px;
 | 
			
		||||
    line-height: 27px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.settings-pane {
 | 
			
		||||
@@ -154,28 +199,36 @@ img.server-info-icon {
 | 
			
		||||
 | 
			
		||||
.server-info {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    padding: 10px;
 | 
			
		||||
    margin: 10px 0 10px 0;
 | 
			
		||||
    padding: 16px 30px;
 | 
			
		||||
    margin: 10px 0 20px 0;
 | 
			
		||||
    background: #fff;
 | 
			
		||||
    border-radius: 2px;
 | 
			
		||||
    width: 540px;
 | 
			
		||||
    box-shadow: 1px 2px 4px #bcbcbc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.hidden {
 | 
			
		||||
    display: none;
 | 
			
		||||
    height: 0 !important;
 | 
			
		||||
    width: 0 !important;
 | 
			
		||||
    margin: 5px !important;
 | 
			
		||||
    opacity: 0 !important;
 | 
			
		||||
    transition: opacity 0.3s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.save-server-button {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    padding: 7px 14px;
 | 
			
		||||
    background-color: #52c2af;
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    border: 0;
 | 
			
		||||
    font-size: 1em;
 | 
			
		||||
    font-weight: 600;
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
 | 
			
		||||
    transition: all .2s ease;
 | 
			
		||||
.red {
 | 
			
		||||
    color: #ef5350;
 | 
			
		||||
    background: #ffebee;
 | 
			
		||||
    border: 1px solid #ef5350;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.save-server-button:hover {
 | 
			
		||||
    background-color: #32a692;
 | 
			
		||||
.green {
 | 
			
		||||
    color: #388E3C;
 | 
			
		||||
    background: #E8F5E9;
 | 
			
		||||
    border: 1px solid #388E3C;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.grey {
 | 
			
		||||
    color: #9E9E9E;
 | 
			
		||||
    background: #FAFAFA;
 | 
			
		||||
    border: 1px solid #9E9E9E;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								app/renderer/js/pages/preference/general-section.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/renderer/js/pages/preference/general-section.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
const {ipcRenderer} = require('electron');
 | 
			
		||||
const BaseComponent = require(__dirname + '/../../components/base.js');
 | 
			
		||||
 | 
			
		||||
class GeneralSection {
 | 
			
		||||
	constructor(props) {
 | 
			
		||||
		this.props = props;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    template() {
 | 
			
		||||
        return `
 | 
			
		||||
            <div class="settings-pane" id="server-settings-pane">
 | 
			
		||||
                <div class="title">Manage Servers</div>
 | 
			
		||||
                <div class="actions-container">
 | 
			
		||||
                    <div class="action green" id="new-server-action">
 | 
			
		||||
                        <i class="material-icons">add_box</i>
 | 
			
		||||
                        <span>New Server</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
				</div>
 | 
			
		||||
                <div id="new-server-container" class="hidden"></div>
 | 
			
		||||
                <div class="sub-title">Existing Servers</div>
 | 
			
		||||
                <div id="server-info-container"></div>
 | 
			
		||||
            </div>
 | 
			
		||||
        `;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	init() {
 | 
			
		||||
        this.props.$root.innerHTML = '';
 | 
			
		||||
		this.initActions();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initActions() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	handleServerInfoChange(index) {
 | 
			
		||||
		ipcRenderer.send('reload-main');
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = GeneralSection;
 | 
			
		||||
@@ -8,7 +8,7 @@ class PreferenceNav extends BaseComponent {
 | 
			
		||||
 | 
			
		||||
		this.props = props;
 | 
			
		||||
 | 
			
		||||
		this.navItems = ['General', 'Server'];
 | 
			
		||||
		this.navItems = ['General', 'Servers'];
 | 
			
		||||
 | 
			
		||||
		this.init();
 | 
			
		||||
	}
 | 
			
		||||
@@ -37,7 +37,9 @@ class PreferenceNav extends BaseComponent {
 | 
			
		||||
	registerListeners() {
 | 
			
		||||
		for (let navItem of this.navItems) {
 | 
			
		||||
			const $item = document.getElementById(`nav-${navItem}`);
 | 
			
		||||
			$item.addEventListener('click', this.props.onItemSelected.bind(navItem));
 | 
			
		||||
			$item.addEventListener('click', event => {
 | 
			
		||||
				this.props.onItemSelected(navItem);
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										80
									
								
								app/renderer/js/pages/preference/new-server-form.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								app/renderer/js/pages/preference/new-server-form.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
const {ipcRenderer} = require('electron');
 | 
			
		||||
const BaseComponent = require(__dirname + '/../../components/base.js');
 | 
			
		||||
 | 
			
		||||
const DomainUtil = require(__dirname + '/../../utils/domain-util.js');
 | 
			
		||||
const Nav = require(__dirname + '/nav.js');
 | 
			
		||||
 | 
			
		||||
class NewServerForm extends BaseComponent{
 | 
			
		||||
	constructor(props) {
 | 
			
		||||
        super();
 | 
			
		||||
		this.props = props;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    template() {
 | 
			
		||||
        return `
 | 
			
		||||
            <div class="server-info" style="border: solid 1px #4CAF50;">
 | 
			
		||||
				<div class="server-info-left">
 | 
			
		||||
					<img class="server-info-icon" src="${__dirname + '../../../../img/icon.png'}"/>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="server-info-right">
 | 
			
		||||
					<div class="server-info-row">
 | 
			
		||||
						<span class="server-info-key">Name</span>
 | 
			
		||||
						<input class="server-info-value" placeholder="(Required)"/>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="server-info-row">
 | 
			
		||||
						<span class="server-info-key">Url</span>
 | 
			
		||||
						<input class="server-info-value" placeholder="(Required)"/>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="server-info-row">
 | 
			
		||||
						<span class="server-info-key">Icon</span>
 | 
			
		||||
						<input class="server-info-value" placeholder="(Optional)"/>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="server-info-row">
 | 
			
		||||
						<span class="server-info-key"></span>
 | 
			
		||||
						<div class="action green server-save-action">
 | 
			
		||||
							<i class="material-icons">check_box</i>
 | 
			
		||||
							<span>Save</span>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
        `;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	init() {
 | 
			
		||||
		this.initForm();
 | 
			
		||||
		this.initActions();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initForm() {
 | 
			
		||||
		this.$newServerForm = this.generateNodeFromTemplate(this.template());
 | 
			
		||||
        this.$saveServerButton = this.$newServerForm.getElementsByClassName('server-save-action')[0];
 | 
			
		||||
        this.props.$root.innerHTML = '';
 | 
			
		||||
		this.props.$root.appendChild(this.$newServerForm);
 | 
			
		||||
 | 
			
		||||
		this.$newServerAlias = this.$newServerForm.querySelectorAll('input.server-info-value')[0];
 | 
			
		||||
		this.$newServerUrl = this.$newServerForm.querySelectorAll('input.server-info-value')[1];
 | 
			
		||||
		this.$newServerIcon = this.$newServerForm.querySelectorAll('input.server-info-value')[2];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	initActions() {
 | 
			
		||||
		this.$saveServerButton.addEventListener('click', () => {
 | 
			
		||||
			DomainUtil.checkDomain(this.$newServerUrl.value).then(domain => {
 | 
			
		||||
				const server = {
 | 
			
		||||
					alias: this.$newServerAlias.value,
 | 
			
		||||
					url: domain,
 | 
			
		||||
					icon: this.$newServerIcon.value
 | 
			
		||||
				};
 | 
			
		||||
				DomainUtil.addDomain(server);
 | 
			
		||||
 | 
			
		||||
            	this.props.onChange(this.props.index);
 | 
			
		||||
			}, errorMessage => {
 | 
			
		||||
				alert(errorMessage);
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = NewServerForm;
 | 
			
		||||
@@ -1,154 +1,44 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
const {ipcRenderer} = require('electron');
 | 
			
		||||
const BaseComponent = require(__dirname + '/js/components/base.js');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const DomainUtil = require(__dirname + '/js/utils/domain-util.js');
 | 
			
		||||
const Nav = require(__dirname + '/js/pages/preference/nav.js');
 | 
			
		||||
const ServersSection = require(__dirname + '/js/pages/preference/servers-section.js');
 | 
			
		||||
const GeneralSection = require(__dirname + '/js/pages/preference/general-section.js');
 | 
			
		||||
 | 
			
		||||
class PreferenceView {
 | 
			
		||||
	constructor() {
 | 
			
		||||
		this.$sidebarContainer = document.getElementById('sidebar');
 | 
			
		||||
		this.$newServerButton = document.getElementById('new-server-action');
 | 
			
		||||
		this.$saveServerButton = document.getElementById('save-server-action');
 | 
			
		||||
		this.$reloadServerButton = document.getElementById('reload-server-action');
 | 
			
		||||
		this.$serverInfoContainer = document.querySelector('.server-info-container');
 | 
			
		||||
		this.$settingsContainer = document.getElementById('settings-container');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	init() {
 | 
			
		||||
		this.nav = new Nav({
 | 
			
		||||
			$root: this.$sidebarContainer,
 | 
			
		||||
			onItemSelected: this.handleNavigation
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		this.nav.activate('Server');
 | 
			
		||||
		this.initServers();
 | 
			
		||||
		this.initActions();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initServers() {
 | 
			
		||||
		const servers = DomainUtil.getDomains();
 | 
			
		||||
		this.$serverInfoContainer.innerHTML = servers.length ? '' : 'Add your first server to get started!';
 | 
			
		||||
		this.$serverInfoContainer.innerHTML = servers.length ? '' : 'Add your first server to get started!';
 | 
			
		||||
 | 
			
		||||
		this.initNewServerForm();
 | 
			
		||||
 | 
			
		||||
		for (const i in servers) {
 | 
			
		||||
			this.initServer(servers[i], i);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initServer(server, index) {
 | 
			
		||||
		const {
 | 
			
		||||
			alias,
 | 
			
		||||
			url,
 | 
			
		||||
			icon
 | 
			
		||||
		} = server;
 | 
			
		||||
		const serverInfoTemplate = `
 | 
			
		||||
				<div class="server-info">
 | 
			
		||||
					<div class="server-info-left">
 | 
			
		||||
						<img class="server-info-icon" src="${icon}"/>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="server-info-right">
 | 
			
		||||
						<div class="server-info-row">
 | 
			
		||||
							<span class="server-info-key">Name</span>
 | 
			
		||||
							<input class="server-info-value" disabled value="${alias}"/>
 | 
			
		||||
						</div>
 | 
			
		||||
						<div class="server-info-row">
 | 
			
		||||
							<span class="server-info-key">Url</span>
 | 
			
		||||
							<input class="server-info-value" disabled value="${url}"/>
 | 
			
		||||
						</div>
 | 
			
		||||
						<div class="server-info-row">
 | 
			
		||||
							<span class="server-info-key">Icon</span>
 | 
			
		||||
							<input class="server-info-value" disabled value="${icon}"/>
 | 
			
		||||
						</div>
 | 
			
		||||
						<div class="server-info-row">
 | 
			
		||||
							<span class="server-info-key">Actions</span>
 | 
			
		||||
							<div class="action server-info-value" id="delete-server-action-${index}">
 | 
			
		||||
								<i class="material-icons">indeterminate_check_box</i>
 | 
			
		||||
								<span>Delete</span>
 | 
			
		||||
							</div>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>`;
 | 
			
		||||
		this.$serverInfoContainer.appendChild(this.insertNode(serverInfoTemplate));
 | 
			
		||||
		document.getElementById(`delete-server-action-${index}`).addEventListener('click', () => {
 | 
			
		||||
			DomainUtil.removeDomain(index);
 | 
			
		||||
			this.initServers();
 | 
			
		||||
			// alert('Success. Reload to apply changes.');
 | 
			
		||||
			ipcRenderer.send('reload-main');
 | 
			
		||||
			this.$reloadServerButton.classList.remove('hidden');
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initNewServerForm() {
 | 
			
		||||
		const newServerFormTemplate = `
 | 
			
		||||
				<div class="server-info active hidden">
 | 
			
		||||
					<div class="server-info-left">
 | 
			
		||||
						<img class="server-info-icon" src="https://chat.zulip.org/static/images/logo/zulip-icon-128x128.271d0f6a0ca2.png"/>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="server-info-right">
 | 
			
		||||
						<div class="server-info-row">
 | 
			
		||||
							<span class="server-info-key">Name</span>
 | 
			
		||||
							<input id="server-info-name" class="server-info-value" placeholder="(Required)"/>
 | 
			
		||||
						</div>
 | 
			
		||||
						<div class="server-info-row">
 | 
			
		||||
							<span class="server-info-key">Url</span>
 | 
			
		||||
							<input id="server-info-url" spellcheck="false" class="server-info-value" placeholder="(Required)"/>
 | 
			
		||||
						</div>
 | 
			
		||||
						<div class="server-info-row">
 | 
			
		||||
							<span class="server-info-key">Icon</span>
 | 
			
		||||
							<input id="server-info-icon" class="server-info-value" placeholder="(Optional)"/>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
		`;
 | 
			
		||||
		this.$serverInfoContainer.appendChild(this.insertNode(newServerFormTemplate));
 | 
			
		||||
 | 
			
		||||
		this.$newServerForm = document.querySelector('.server-info.active');
 | 
			
		||||
		this.$newServerAlias = this.$newServerForm.querySelectorAll('input.server-info-value')[0];
 | 
			
		||||
		this.$newServerUrl = this.$newServerForm.querySelectorAll('input.server-info-value')[1];
 | 
			
		||||
		this.$newServerIcon = this.$newServerForm.querySelectorAll('input.server-info-value')[2];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initActions() {
 | 
			
		||||
		this.$newServerButton.addEventListener('click', () => {
 | 
			
		||||
			this.$newServerForm.classList.remove('hidden');
 | 
			
		||||
			this.$saveServerButton.classList.remove('hidden');
 | 
			
		||||
			this.$newServerButton.classList.add('hidden');
 | 
			
		||||
		});
 | 
			
		||||
		this.$saveServerButton.addEventListener('click', () => {
 | 
			
		||||
			DomainUtil.checkDomain(this.$newServerUrl.value).then(domain => {
 | 
			
		||||
				const server = {
 | 
			
		||||
					alias: this.$newServerAlias.value,
 | 
			
		||||
					url: domain,
 | 
			
		||||
					icon: this.$newServerIcon.value
 | 
			
		||||
				};
 | 
			
		||||
				DomainUtil.addDomain(server);
 | 
			
		||||
				this.$saveServerButton.classList.add('hidden');
 | 
			
		||||
				this.$newServerButton.classList.remove('hidden');
 | 
			
		||||
				this.$newServerForm.classList.add('hidden');
 | 
			
		||||
 | 
			
		||||
				this.initServers();
 | 
			
		||||
				// alert('Success. Reload to apply changes.');
 | 
			
		||||
				ipcRenderer.send('reload-main');
 | 
			
		||||
				this.$reloadServerButton.classList.remove('hidden');
 | 
			
		||||
			}, errorMessage => {
 | 
			
		||||
				alert(errorMessage);
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
		this.$reloadServerButton.addEventListener('click', () => {
 | 
			
		||||
			ipcRenderer.send('reload-main');
 | 
			
		||||
			onItemSelected: this.handleNavigation.bind(this)
 | 
			
		||||
		});
 | 
			
		||||
		this.handleNavigation('General');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	handleNavigation(navItem) {
 | 
			
		||||
 | 
			
		||||
		this.nav.select(navItem);
 | 
			
		||||
		switch (navItem) {
 | 
			
		||||
			case 'Servers': {
 | 
			
		||||
				this.section = new ServersSection({
 | 
			
		||||
					$root: this.$settingsContainer
 | 
			
		||||
				});
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
	insertNode(html) {
 | 
			
		||||
		const wrapper = document.createElement('div');
 | 
			
		||||
		wrapper.innerHTML = html;
 | 
			
		||||
		return wrapper.firstElementChild;
 | 
			
		||||
			case 'General': {
 | 
			
		||||
				this.section = new GeneralSection({
 | 
			
		||||
					$root: this.$settingsContainer
 | 
			
		||||
				});
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		this.section.init();		
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										65
									
								
								app/renderer/js/pages/preference/server-info-form.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								app/renderer/js/pages/preference/server-info-form.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
const {ipcRenderer} = require('electron');
 | 
			
		||||
const BaseComponent = require(__dirname + '/../../components/base.js');
 | 
			
		||||
 | 
			
		||||
const DomainUtil = require(__dirname + '/../../utils/domain-util.js');
 | 
			
		||||
const Nav = require(__dirname + '/nav.js');
 | 
			
		||||
 | 
			
		||||
class ServerInfoForm extends BaseComponent{
 | 
			
		||||
	constructor(props) {
 | 
			
		||||
        super();
 | 
			
		||||
		this.props = props;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    template() {
 | 
			
		||||
        return `
 | 
			
		||||
            <div class="server-info">
 | 
			
		||||
				<div class="server-info-left">
 | 
			
		||||
					<img class="server-info-icon" src="${this.props.server.icon}"/>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="server-info-right">
 | 
			
		||||
					<div class="server-info-row">
 | 
			
		||||
						<span class="server-info-key">Name</span>
 | 
			
		||||
						<input class="server-info-value" disabled value="${this.props.server.alias}"/>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="server-info-row">
 | 
			
		||||
						<span class="server-info-key">Url</span>
 | 
			
		||||
						<input class="server-info-value" disabled value="${this.props.server.url}"/>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="server-info-row">
 | 
			
		||||
						<span class="server-info-key">Icon</span>
 | 
			
		||||
						<input class="server-info-value" disabled value="${this.props.server.icon}"/>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="server-info-row">
 | 
			
		||||
						<span class="server-info-key"></span>
 | 
			
		||||
						<div class="action red server-delete-action">
 | 
			
		||||
							<i class="material-icons">indeterminate_check_box</i>
 | 
			
		||||
							<span>Delete</span>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
        `;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	init() {
 | 
			
		||||
		this.initForm();
 | 
			
		||||
		this.initActions();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initForm() {
 | 
			
		||||
		this.$serverInfoForm = this.generateNodeFromTemplate(this.template());
 | 
			
		||||
        this.$deleteServerButton = this.$serverInfoForm.getElementsByClassName('server-delete-action')[0];
 | 
			
		||||
        this.props.$root.appendChild(this.$serverInfoForm);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	initActions() {
 | 
			
		||||
		this.$deleteServerButton.addEventListener('click', () => {
 | 
			
		||||
			DomainUtil.removeDomain(this.props.index);
 | 
			
		||||
            this.props.onChange(this.props.index);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = ServerInfoForm;
 | 
			
		||||
							
								
								
									
										81
									
								
								app/renderer/js/pages/preference/servers-section.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								app/renderer/js/pages/preference/servers-section.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
'use strict';
 | 
			
		||||
 | 
			
		||||
const {ipcRenderer} = require('electron');
 | 
			
		||||
const BaseComponent = require(__dirname + '/../../components/base.js');
 | 
			
		||||
 | 
			
		||||
const DomainUtil = require(__dirname + '/../../utils/domain-util.js');
 | 
			
		||||
const Nav = require(__dirname + '/nav.js');
 | 
			
		||||
const ServerInfoForm = require(__dirname + '/server-info-form.js');
 | 
			
		||||
const NewServerForm = require(__dirname + '/new-server-form.js');
 | 
			
		||||
 | 
			
		||||
class ServersSection {
 | 
			
		||||
	constructor(props) {
 | 
			
		||||
		this.props = props;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    template() {
 | 
			
		||||
        return `
 | 
			
		||||
            <div class="settings-pane" id="server-settings-pane">
 | 
			
		||||
                <div class="title">Manage Servers</div>
 | 
			
		||||
                <div class="actions-container">
 | 
			
		||||
                    <div class="action green" id="new-server-action">
 | 
			
		||||
                        <i class="material-icons">add_box</i>
 | 
			
		||||
                        <span>New Server</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
				</div>
 | 
			
		||||
                <div id="new-server-container" class="hidden"></div>
 | 
			
		||||
                <div class="sub-title">Existing Servers</div>
 | 
			
		||||
                <div id="server-info-container"></div>
 | 
			
		||||
            </div>
 | 
			
		||||
        `;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	init() {
 | 
			
		||||
		this.initServers();
 | 
			
		||||
		this.initActions();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initServers() {
 | 
			
		||||
		this.props.$root.innerHTML = '';
 | 
			
		||||
 | 
			
		||||
		const servers = DomainUtil.getDomains();
 | 
			
		||||
		this.props.$root.innerHTML = this.template();
 | 
			
		||||
		this.$serverInfoContainer = document.getElementById('server-info-container');
 | 
			
		||||
		this.$newServerContainer = document.getElementById('new-server-container');
 | 
			
		||||
		this.$newServerButton = document.getElementById('new-server-action');
 | 
			
		||||
		
 | 
			
		||||
		this.$serverInfoContainer.innerHTML = servers.length ? '' : 'Add your first server to get started!';
 | 
			
		||||
 | 
			
		||||
		this.initNewServerForm();
 | 
			
		||||
 | 
			
		||||
		for (const i in servers) {
 | 
			
		||||
			new ServerInfoForm({
 | 
			
		||||
				$root: this.$serverInfoContainer,
 | 
			
		||||
				server: servers[i],
 | 
			
		||||
				index: i,
 | 
			
		||||
				onChange: this.handleServerInfoChange.bind(this)
 | 
			
		||||
			}).init();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initNewServerForm() {
 | 
			
		||||
		new NewServerForm({
 | 
			
		||||
			$root: this.$newServerContainer,
 | 
			
		||||
			onChange: this.handleServerInfoChange.bind(this)
 | 
			
		||||
		}).init();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	initActions() {
 | 
			
		||||
		this.$newServerButton.addEventListener('click', () => {
 | 
			
		||||
			this.$newServerContainer.classList.remove('hidden');
 | 
			
		||||
			this.$newServerButton.classList.remove('green');
 | 
			
		||||
			this.$newServerButton.classList.add('grey');
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	handleServerInfoChange(index) {
 | 
			
		||||
		ipcRenderer.send('reload-main');
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = ServersSection;
 | 
			
		||||
@@ -5,32 +5,11 @@
 | 
			
		||||
    <meta name="viewport" content="width=device-width">
 | 
			
		||||
    <title>Zulip - Settings</title>
 | 
			
		||||
    <link rel="stylesheet" href="css/preference.css" type="text/css" media="screen">
 | 
			
		||||
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div id="content">
 | 
			
		||||
      <div id="sidebar"></div>
 | 
			
		||||
      <div id="settings-container">
 | 
			
		||||
        <div class="settings-pane" id="server-settings-pane">
 | 
			
		||||
            <div class="title">Manage Servers</div>
 | 
			
		||||
            <div class="actions-container">
 | 
			
		||||
                <div class="action" id="new-server-action">
 | 
			
		||||
                    <i class="material-icons">add_box</i>
 | 
			
		||||
                    <span>New Server</span>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="action hidden" id="save-server-action">
 | 
			
		||||
                    <button class="save-server-button">Save</button>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="action hidden" id="reload-server-action">
 | 
			
		||||
                    <i class="material-icons">refresh</i>
 | 
			
		||||
                    <span>Reload to Apply Changes</span>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="server-info-container">
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div id="settings-container"></div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </body>
 | 
			
		||||
  <script src="js/pages/preference/preference.js"></script>  
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user