1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-18 20:59:43 +02:00

experimental electron-based desktop app support

This commit is contained in:
Harvey Kandola 2016-12-02 18:25:02 -08:00
parent 3b3785ba24
commit 43b1a39a5a
29 changed files with 273 additions and 62 deletions

View file

@ -35,6 +35,12 @@ export default Base.extend({
authenticate(credentials) {
let domain = netUtil.getSubdomain();
if (is.empty(domain)) {
console.log(domain);
domain = "demo1";
console.log(domain);
}
let encoded;
if (typeof credentials === 'object') {

View file

@ -24,14 +24,20 @@ export default Ember.Component.extend({
didRender() {
let self = this;
let assetUrl = this.session.get('assetURL');
// handle desktop app
if (assetUrl === null) {
assetUrl = '';
}
$("#stage-1-firstname").focus();
// Stage 1 - person name keypress handler
$("#stage-1-firstname, #stage-1-lastname").keyup(function() {
if (!$("#stage-1-firstname").val() || !$("#stage-1-lastname").val()) {
$(".name-status").attr("src", "/assets/img/onboard/person-red.png");
$(".name-status").attr("src", assetUrl + "assets/img/onboard/person-red.png");
} else {
$(".name-status").attr("src", "/assets/img/onboard/person-green.png");
$(".name-status").attr("src", assetUrl + "assets/img/onboard/person-green.png");
}
});
@ -40,14 +46,14 @@ export default Ember.Component.extend({
if (!$("#stage-1-firstname").val()) {
$("#stage-1-firstname").focus();
$("#stage-1-firstname").addClass("error");
$(".name-status").attr("src", "/assets/img/onboard/person-red.png");
$(".name-status").attr("src", assetUrl + "assets/img/onboard/person-red.png");
return;
}
if (!$("#stage-1-lastname").val()) {
$("#stage-1-lastname").focus();
$("#stage-1-lastname").addClass("error");
$(".name-status").attr("src", "/assets/img/onboard/person-red.png");
$(".name-status").attr("src", assetUrl + "assets/img/onboard/person-red.png");
return;
}
@ -67,9 +73,9 @@ export default Ember.Component.extend({
$("#stage-2-password-confirm").keyup(function() {
if ($("#stage-2-password").val().length < 6 || $("#stage-2-password").val().length > 50 ||
($("#stage-2-password").val() !== $("#stage-2-password-confirm").val())) {
$(".password-status").attr("src", "/assets/img/onboard/lock-red.png");
$(".password-status").attr("src", assetUrl + "assets/img/onboard/lock-red.png");
} else {
$(".password-status").attr("src", "/assets/img/onboard/lock-green.png");
$(".password-status").attr("src", assetUrl + "assets/img/onboard/lock-green.png");
}
});
});
@ -91,7 +97,7 @@ export default Ember.Component.extend({
if ($("#stage-2-password-confirm").val() !== $("#stage-2-password").val()) {
$(".mismatch").show();
$(".password-status").attr("src", "/assets/img/onboard/lock-red.png");
$(".password-status").attr("src", assetUrl + "assets/img/onboard/lock-red.png");
return;
}

View file

@ -23,7 +23,13 @@ export default Ember.Component.extend(TooltipMixin, {
this._super(...arguments);
let self = this;
CodeMirror.modeURL = "/codemirror/mode/%N/%N.js";
// handle desktop app
if (this.session.get('assetURL') === null) {
CodeMirror.modeURL = "codemirror/mode/%N/%N.js";
} else {
CodeMirror.modeURL = "/codemirror/mode/%N/%N.js";
}
let rawBody = this.get('meta.rawBody');
let cleanBody = rawBody.replace("</pre>", "");

View file

@ -16,7 +16,11 @@ export default Ember.Component.extend({
codeSyntax: "htmlmixed",
didReceiveAttrs() {
CodeMirror.modeURL = "/codemirror/mode/%N/%N.js";
if (this.session.get('assetURL') === null) {
CodeMirror.modeURL = "codemirror/mode/%N/%N.js";
} else {
CodeMirror.modeURL = "/codemirror/mode/%N/%N.js";
}
let page = this.get('page');
let rawBody = page.get('body');

View file

@ -67,9 +67,18 @@ export default Ember.Component.extend({
};
if (typeof tinymce === 'undefined') {
$.getScript("/tinymce/tinymce.min.js?v=443", function () {
let url = this.session.get('assetURL');
let tinymceBaseURL = "//" + window.location.host + "/tinymce";
// handle desktop app
if (url === null) {
url = '';
tinymceBaseURL = "tinymce";
}
$.getScript(url + "tinymce/tinymce.min.js?v=443", function () {
window.tinymce.dom.Event.domLoaded = true;
tinymce.baseURL = "//" + window.location.host + "/tinymce";
tinymce.baseURL = tinymceBaseURL;
tinymce.suffix = ".min";
tinymce.init(options);
});

View file

@ -11,22 +11,22 @@
<meta name="author" content="Documize" />
<meta name="description" content="Documize">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="shortcut icon" href="/favicon.ico?v=1.1" />
<link rel="icon" type="image/png" href="/favicon-32x32.png?v=1.1" sizes="32x32" />
<link rel="stylesheet" href="/assets/vendor.css">
<link rel="stylesheet" href="/assets/documize.css">
<link rel="shortcut icon" href="{{rootURL}}favicon.ico?v=1.1" />
<link rel="icon" type="image/png" href="{{rootURL}}favicon-32x32.png?v=1.1" sizes="32x32" />
<link rel="stylesheet" href="{{rootURL}}assets/vendor.css">
<link rel="stylesheet" href="{{rootURL}}assets/documize.css">
{{content-for 'head-footer'}}
</head>
<body>
{{content-for 'body'}}
<script src="/assets/vendor.js"></script>
<script src="/assets/documize.js"></script>
<script src="/codemirror/lib/codemirror.js"></script>
<script src="/codemirror/mode/meta.js"></script>
<script src="/codemirror/addon/mode/loadmode.js"></script>
<script src="/codemirror/addon/runmode/runmode.js"></script>
<script src="/codemirror/addon/runmode/colorize.js"></script>
<script src="{{rootURL}}assets/vendor.js"></script>
<script src="{{rootURL}}assets/documize.js"></script>
<script src="{{rootURL}}codemirror/lib/codemirror.js"></script>
<script src="{{rootURL}}codemirror/mode/meta.js"></script>
<script src="{{rootURL}}codemirror/addon/mode/loadmode.js"></script>
<script src="{{rootURL}}codemirror/addon/runmode/runmode.js"></script>
<script src="{{rootURL}}codemirror/addon/runmode/colorize.js"></script>
{{content-for 'body-footer'}}
</body>

View file

@ -9,7 +9,9 @@
//
// https://documize.com
export function initialize( /*application*/ ) {
// import env from '../config/environment';
export function initialize(/*application*/) {
// address insecure jquery defaults (kudos: @nathanhammond)
$.globalEval = function() {};
$.ajaxSetup({

View file

@ -1,6 +1,6 @@
<div class="auth-box">
<div class="logo">
<img src="/assets/img/logo-color.png" title="Documize" alt="Documize" class="responsive-img" />
<img src="{{session.assetURL}}assets/img/logo-color.png" title="Documize" alt="Documize" class="responsive-img" />
</div>
<div class="login-form">
{{forgot-password forgot=(action 'forgot')}}

View file

@ -1,6 +1,6 @@
<div class="auth-box">
<div class="logo">
<img src="/assets/img/logo-color.png" title="Documize" alt="Documize" class="responsive-img" />
<img src="{{session.assetURL}}assets/img/logo-color.png" title="Documize" alt="Documize" class="responsive-img" />
</div>
<div class="login-form">
<form id="login-form" {{action 'login' on="submit"}}>

View file

@ -1,6 +1,6 @@
<div class="auth-box">
<div class="logo">
<img src="/assets/img/logo-color.png" title="Documize" alt="Documize" class="responsive-img" />
<img src="{{session.assetURL}}assets/img/logo-color.png" title="Documize" alt="Documize" class="responsive-img" />
</div>
{{password-reset reset=(action 'reset')}}
</div>

View file

@ -1,4 +1,4 @@
<div class="sso-box">
<p>Signing in...</p>
<img src="/assets/img/busy-gray.gif" />
<img src="{{session.assetURL}}assets/img/busy-gray.gif" />
</div>

View file

@ -2,10 +2,10 @@
<div class="row">
<div class="col-lg-3 col-md-3 col-sm-3">
<div>
<img src="/assets/img/setup/logo.png" alt="Documize" class="no-select no-outline margin-top-20" />
<img src="{{session.assetURL}}assets/img/setup/logo.png" alt="Documize" class="no-select no-outline margin-top-20" />
</div>
<div class="margin-top-150">
<img src="/assets/img/setup/cogs.png" width="157" height="187" alt="Setup new database" class="no-select no-outline" />
<img src="{{session.assetURL}}assets/img/setup/cogs.png" width="157" height="187" alt="Setup new database" class="no-select no-outline" />
</div>
</div>
{{documize-setup model=model save=(action 'save')}}

View file

@ -11,6 +11,7 @@
import Ember from 'ember';
import SimpleAuthSession from 'ember-simple-auth/services/session';
import config from '../config/environment';
const {
inject: { service },
@ -39,12 +40,15 @@ export default SimpleAuthSession.extend({
let data = this.get('user');
return data.get('global');
}),
assetURL: null,
init: function () {
this._super(...arguments);
this.set('isMac', is.mac());
this.set('isMobile', is.mobile());
this.set('assetURL', config.rootURL);
},
user: computed('isAuthenticated', 'session.content.authenticated.user', function () {

View file

@ -2,7 +2,7 @@
<ul class="list">
{{#each files key="id" as |a index|}}
<li class="item">
<img class="icon" src="/assets/img/attachments/{{document/file-icon a.extension}}" />
<img class="icon" src="{{session.assetURL}}assets/img/attachments/{{document/file-icon a.extension}}" />
<a href="{{ appMeta.endpoint }}/public/attachments/{{ appMeta.orgId }}/{{ a.id }}">
<span class="file">{{ a.filename }}</span>
</a>

View file

@ -27,6 +27,6 @@
{{#if noSections}}
<div class="empty-state-document">
<img src="/assets/img/empty-state-document.gif" />
<img src="{{session.assetURL}}assets/img/empty-state-document.gif" />
</div>
{{/if}}

View file

@ -31,7 +31,7 @@
{{#each candidates.attachments as |a|}}
<li class="link-item" {{ action 'setSelection' a }}>
{{#ui/ui-selection selected=a.selected}}
<img class="icon" src="/assets/img/attachments/{{document/file-icon a.context}}" />
<img class="icon" src="{{session.assetURL}}assets/img/attachments/{{document/file-icon a.context}}" />
{{ a.title }}
{{/ui/ui-selection}}
</li>
@ -66,7 +66,7 @@
{{#each matches.attachments as |a|}}
<li class="link-item" {{ action 'setSelection' a }}>
{{#ui/ui-selection selected=a.selected}}
<img class="icon" src="/assets/img/attachments/{{document/file-icon a.context}}" />
<img class="icon" src="{{session.assetURL}}assets/img/attachments/{{document/file-icon a.context}}" />
{{ a.title }}
{{/ui/ui-selection}}
</li>

View file

@ -33,7 +33,7 @@
</div>
{{#if busy}}
<div class="processing">
<img src="/assets/img/processing.gif" />
<img src="{{session.assetURL}}assets/img/processing.gif" />
<div class="caption">Preparing</div>
</div>
{{/if}}

View file

@ -4,7 +4,7 @@
{{#each sections as |section|}}
<li class="item" {{action 'addSection' section}}>
<div class="icon">
<img class="img" src="/sections/{{section.contentType}}.png" srcset="/sections/{{section.contentType}}@2x.png" />
<img class="img" src="{{session.assetURL}}sections/{{section.contentType}}.png" srcset="{{session.assetURL}}sections/{{section.contentType}}@2x.png" />
</div>
<div class="details">
<div class='title'>

View file

@ -21,6 +21,6 @@
{{#if emptyState}}
<div class="empty-state-space">
<img src="/assets/img/empty-state-space.gif" />
<img src="{{session.assetURL}}assets/img/empty-state-space.gif" />
</div>
{{/if}}

View file

@ -9,7 +9,7 @@
{{#each savedTemplates key="id" as |template|}}
<li class="item">
<div class="icon">
<img class="img" src="/assets/img/{{template.img}}.png" srcset="/assets/img/{{template.img}}@2x.png" />
<img class="img" src="{{session.assetURL}}assets/img/{{template.img}}.png" srcset="{{session.assetURL}}assets/img/{{template.img}}@2x.png" />
{{#if editor}}
{{#unless template.locked}}
<div class="edit-control" {{action 'editTemplate' template}}>edit</div>

View file

@ -1,7 +1,7 @@
<div class="col-lg-4 col-md-4 col-sm-4">
<div class="sidebar">
<img class="logo" src="/assets/img/logo-color.png"/>
<img class="logo" src="{{session.assetURL}}assets/img/logo-color.png"/>
<div class="stage-1">
<h2>Documize Sign-up</h2>
@ -52,7 +52,7 @@
<div class="account-name-preview">
<div class="nav-icon"></div>
<div class="title">DOCUMIZE</div>
<img class="name-status" src="/assets/img/onboard/person.png" />
<img class="name-status" src="{{session.assetURL}}assets/img/onboard/person.png" />
</div>
</div>
@ -60,7 +60,7 @@
<div class="account-name-preview">
<div class="nav-icon"></div>
<div class="title">DOCUMIZE</div>
<img class="password-status" src="/assets/img/onboard/lock.png" />
<img class="password-status" src="{{session.assetURL}}assets/img/onboard/lock.png" />
</div>
</div>

View file

@ -9,7 +9,7 @@
</div>
<div class="buttons pull-right">
{{#if busy}}
<img src="/assets/img/busy-gray.gif" class="busy-indicator" />
<img src="{{session.assetURL}}assets/img/busy-gray.gif" class="busy-indicator" />
{{/if}}
<div id="editor-cancel" class="flat-button flat-gray" {{action 'onCancel'}}>{{cancelLabel}}</div>
<div class="button-gap" />

View file

@ -16,10 +16,9 @@ module.exports = function (environment) {
var ENV = {
modulePrefix: 'documize',
podModulePrefix: 'documize/pods',
locationType: 'auto',
locationType: process.env.EMBER_CLI_ELECTRON ? 'hash' : 'auto',
environment: environment,
rootURL: '/',
// baseURL: '/',
rootURL: process.env.EMBER_CLI_ELECTRON ? null : '/',
apiHost: '',
apiNamespace: '',
contentSecurityPolicyHeader: 'Content-Security-Policy-Report-Only',

91
app/electron.js Normal file
View file

@ -0,0 +1,91 @@
/* jshint node: true */
'use strict';
const electron = require('electron');
const path = require('path');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const dirname = __dirname || path.resolve(path.dirname());
const emberAppLocation = `file://${dirname}/dist/index.html`;
let mainWindow = null;
// Uncomment the lines below to enable Electron's crash reporter
// For more information, see http://electron.atom.io/docs/api/crash-reporter/
// electron.crashReporter.start({
// productName: 'YourName',
// companyName: 'YourCompany',
// submitURL: 'https://your-domain.com/url-to-submit',
// autoSubmit: true
// });
app.on('window-all-closed', function onWindowAllClosed() {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('ready', function onReady() {
mainWindow = new BrowserWindow({
width: 1300,
height: 900
});
delete mainWindow.module;
// If you want to open up dev tools programmatically, call
// mainWindow.openDevTools();
// By default, we'll open the Ember App by directly going to the
// file system.
//
// Please ensure that you have set the locationType option in the
// config/environment.js file to 'hash'. For more information,
// please consult the ember-electron readme.
mainWindow.loadURL(emberAppLocation);
// If a loading operation goes wrong, we'll send Electron back to
// Ember App entry point
mainWindow.webContents.on('did-fail-load', () => {
mainWindow.loadURL(emberAppLocation);
});
mainWindow.webContents.on('crashed', () => {
console.log('Your Ember app (or other code) in the main window has crashed.');
console.log('This is a serious issue that needs to be handled and/or debugged.');
});
mainWindow.on('unresponsive', () => {
console.log('Your Ember app (or other code) has made the window unresponsive.');
});
mainWindow.on('responsive', () => {
console.log('The main window has become responsive again.');
});
mainWindow.on('closed', () => {
mainWindow = null;
});
// Handle an unhandled error in the main thread
//
// Note that 'uncaughtException' is a crude mechanism for exception handling intended to
// be used only as a last resort. The event should not be used as an equivalent to
// "On Error Resume Next". Unhandled exceptions inherently mean that an application is in
// an undefined state. Attempting to resume application code without properly recovering
// from the exception can cause additional unforeseen and unpredictable issues.
//
// Attempting to resume normally after an uncaught exception can be similar to pulling out
// of the power cord when upgrading a computer -- nine out of ten times nothing happens -
// but the 10th time, the system becomes corrupted.
//
// The correct use of 'uncaughtException' is to perform synchronous cleanup of allocated
// resources (e.g. file descriptors, handles, etc) before shutting down the process. It is
// not safe to resume normal operation after 'uncaughtException'.
process.on('uncaughtException', (err) => {
console.log('An exception in the main thread was not handled.');
console.log('This is a serious issue that needs to be handled and/or debugged.');
console.log(`Exception: ${err}`);
});
});

View file

@ -13,7 +13,6 @@
"start": "ember server",
"test": "ember test"
},
"repository": "",
"engines": {
"node": ">= 0.10.0"
},
@ -21,6 +20,10 @@
"license": "AGPL",
"devDependencies": {
"broccoli-asset-rev": "^2.4.5",
"devtron": "^1.4.0",
"electron": "^1.4.10",
"electron-packager": "^8.3.0",
"electron-rebuild": "^1.4.0",
"ember-ajax": "^2.4.1",
"ember-cli": "2.10.0",
"ember-cli-app-version": "^2.0.0",
@ -38,7 +41,9 @@
"ember-cli-test-loader": "^1.1.0",
"ember-cli-uglify": "^1.2.0",
"ember-data": "^2.10.0",
"ember-electron": "1.10.8",
"ember-export-application-global": "^1.0.5",
"ember-inspector": "^2.0.4",
"ember-load-initializers": "^0.5.1",
"ember-resolver": "^2.0.3",
"ember-simple-auth": "git+https://github.com/documize/ember-simple-auth.git#21e638f9e33267d8944835002ee96884d34d568a",
@ -48,5 +53,47 @@
"paths": [
"lib/intercom"
]
},
"main": "electron.js",
"ember-electron": {
"WHAT IS THIS?": "Please see the README.md",
"copy-files": [
"electron.js",
"package.json"
],
"name": null,
"platform": null,
"arch": null,
"version": null,
"app-bundle-id": null,
"app-category-type": null,
"app-copyright": null,
"app-version": null,
"asar": null,
"asar-unpack": null,
"asar-unpack-dir": null,
"build-version": null,
"cache": null,
"extend-info": null,
"extra-resource": null,
"helper-bundle-id": null,
"icon": null,
"ignore": null,
"out": null,
"osx-sign": {
"identity": null,
"entitlements": null,
"entitlements-inherit": null
},
"overwrite": null,
"prune": null,
"strict-ssl": null,
"version-string": {
"CompanyName": null,
"FileDescription": null,
"OriginalFilename": null,
"ProductName": null,
"InternalName": null
}
}
}

33
app/tests/electron.js Normal file
View file

@ -0,0 +1,33 @@
/* jshint undef: false */
const BrowserWindow = require('electron').BrowserWindow;
const app = require('electron').app;
let mainWindow = null;
app.on('window-all-closed', function onWindowAllClosed() {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('ready', function onReady() {
mainWindow = new BrowserWindow({
width: 800,
height: 600
});
delete mainWindow.module;
if (process.env.EMBER_ENV === 'test') {
mainWindow.loadURL('file://' + __dirname + '/index.html');
} else {
mainWindow.loadURL('file://' + __dirname + '/dist/index.html');
}
mainWindow.on('closed', function onClosed() {
mainWindow = null;
});
});
/* jshint undef: true */

4
app/tests/package.json Normal file
View file

@ -0,0 +1,4 @@
{
"name": "ember-electron-test",
"main": "electron.js"
}