silex-website-builder-goodevent
Version:
Free and easy website builder for everyone.
336 lines (316 loc) • 11.8 kB
text/typescript
/**
* Silex, live web creation
* http://projects.silexlabs.org/?/silex/
*
* Copyright (c) 2012 Silex Labs
* http://www.silexlabs.org/
*
* Silex is available under the GPL license
* http://www.silexlabs.org/silex/silex-licensing/
*/
/**
* @fileoverview A controller listens to a view element,
* and call the main {silex.controller.Controller} controller's methods
*
*/
import { Config } from '../ClientConfig';
import { CloudStorage } from '../service/cloud-storage';
import { SilexTasks } from '../service/silex-tasks';
import { FileInfo, Model, Provider, PublicationOptions, View } from '../types';
import { SilexNotification } from '../utils/notification';
import { FileExplorer } from '../view/dialog/file-explorer';
import { PublishDialog } from '../view/dialog/PublishDialog';
import { ControllerBase } from './controller-base';
/**
* @param view view class which holds the other views
*/
export class FileMenuController extends ControllerBase {
constructor(model: Model, view: View) {
super(model, view);
}
loadTemplate(
url, opt_cbk?: (() => any),
opt_errorCbk?: ((p1: any) => any)) {
this.model.file.openFromUrl(
url, (rawHtml) => this.onOpened(opt_cbk, rawHtml),
(err, msg) => this.onOpenError(err, msg, opt_errorCbk));
}
/**
* load blank template
*/
loadBlank(
opt_cbk?: (() => any), opt_errorCbk?: ((p1: any) => any)) {
const blankUrl =
'/libs/templates/silex-blank-templates/blank/editable.html';
this.loadTemplate(blankUrl, opt_cbk, opt_errorCbk);
}
openRecent(fileInfo, opt_cbk) {
// a recent file was selected
this.model.file.open(
(fileInfo as FileInfo), (rawHtml) => this.onOpened(opt_cbk, rawHtml),
(err) => {
SilexNotification.confirm('Open recent file', `
Could not open this recent file, you probably need to connect to ${fileInfo.service} again.
`,
(ok) => {
const ce = CloudStorage.getInstance().ce;
SilexNotification.alert('Open recent file', `
I am trying to connect you to ${fileInfo.service} again,
please accept the connection in the popup I have just opened then <strong>please wait</strong>.
`, () => {});
// tslint:disable:no-string-literal
ce['auth'](fileInfo.service).then((res) => {
SilexNotification.close();
if (ok) {
this.openRecent(fileInfo, opt_cbk);
}
});
});
});
}
/**
* open a file
*/
newFile(
opt_cbk?: (() => any), opt_errorCbk?: ((p1: any) => any)) {
this.tracker.trackAction('controller-events', 'request', 'file.new', 0);
this.view.dashboard.openDialog({
openFileInfo: (fileInfo) => {
if (!fileInfo && !this.model.file.hasContent()) {
// if the user closes the dialog and no website is being edited then
// load default blank website
this.loadBlank(opt_cbk, opt_errorCbk);
} else {
if (fileInfo) {
this.openRecent(fileInfo, opt_cbk);
}
}
},
openTemplate: (url) => {
if (!url && !this.model.file.hasContent()) {
// if the user closes the dialog and no website is being edited then
// load default blank website
this.loadBlank(opt_cbk, opt_errorCbk);
} else {
if (url) {
// a template was selected
this.loadTemplate(url, opt_cbk, opt_errorCbk);
}
}
},
ready: () => {
if (opt_cbk) {
opt_cbk();
}
},
error: (err) => {
console.error('loading templates error');
this.onOpenError(err, 'Loading templates error', opt_errorCbk);
},
});
}
onOpened(opt_cbk, rawHtml) {
// reset file URL in order to "save as" instead of "save"
// this.model.file.setUrl(null);
this.model.file.setHtml(rawHtml, () => {
// undo redo reset
this.undoReset();
this.fileOperationSuccess(null, true);
}, true);
// with loader
// QOS, track success
this.tracker.trackAction('controller-events', 'success', 'file.new', 1);
if (opt_cbk) {
opt_cbk();
}
}
onOpenError(err: any, msg: string, opt_errorCbk?: ((p1: any) => any)) {
console.error('opening template error', err);
SilexNotification.alert('Open file', 'An error occured. ' + msg, () => {});
if (opt_errorCbk) {
opt_errorCbk(err);
}
if (!this.model.file.hasContent()) {
this.loadBlank();
}
this.tracker.trackAction('controller-events', 'error', 'file.new', -1);
}
/**
* open a file
*/
openFile(opt_cbk?: ((p1: FileInfo) => any), opt_errorCbk?: ((p1: any) => any), opt_cancelCbk?: (() => any)) {
// QOS, track success
this.tracker.trackAction('controller-events', 'request', 'file.open', 0);
// let the user choose the file
this.view.fileExplorer.openFile(FileExplorer.HTML_EXTENSIONS)
.then((fileInfo) => {
if (fileInfo) {
this.model.file.open(
fileInfo,
(rawHtml) => {
this.model.file.setHtml(rawHtml, () => {
// undo redo reset
this.undoReset();
// display and redraw
this.fileOperationSuccess(
(this.model.head.getTitle() || 'Untitled website') +
' opened.',
true);
// QOS, track success
this.tracker.trackAction(
'controller-events', 'success', 'file.open', 1);
if (opt_cbk) {
opt_cbk((fileInfo as FileInfo));
}
}, true);
},
// with loader
(error: any, message) => {
SilexNotification.alert('Open file', 'Error: I did not manage to open this file. \n' + (message || error.message || ''),
() => {
if (opt_errorCbk) {
opt_errorCbk(error);
}
});
this.tracker.trackAction('controller-events', 'error', 'file.open', -1);
});
} else {
if (opt_cancelCbk) {
opt_cancelCbk();
}
}
})
.catch((error) => {
this.tracker.trackAction(
'controller-events', 'error', 'file.open', -1);
if (opt_errorCbk) {
opt_errorCbk(error);
}
});
}
publishError(message) {
this.tracker.trackAction('controller-events', 'error', 'file.publish', -1);
console.error('Error: I did not manage to publish the file.', message);
SilexNotification.alert('Publication',
`<strong>An error occured.</strong><p>I did not manage to publish the website. ${
message}</p><p><a href="${ Config.ISSUES_SILEX }" target="_blank">Get help in Silex forums.</a></p>`,
() => {});
}
/**
* ask the user for a new file title
* handle tracking and call the Dom helper
*/
publish() {
if (SilexNotification.isActive) {
console.warn(
'Publish canceled because a modal dialog is opened already.');
return;
}
this.tracker.trackAction('controller-events', 'request', 'file.publish', 0);
const dialog: PublishDialog = new PublishDialog(this.model, this.view);
dialog.open()
.then((publishOptions: PublicationOptions) => {
if (publishOptions) {
this.doPublish(publishOptions, (errMsg, warningMsg, finalPublicationOptions) => {
if (errMsg) {
dialog.close();
this.publishError(errMsg);
} else {
if (warningMsg) {
dialog.close();
SilexNotification.alert('Publication', warningMsg, () => {});
this.tracker.trackAction(
'controller-events', 'cancel', 'file.publish', 0);
} else {
dialog
.publish((finalPublicationOptions as PublicationOptions))
.then((msg: string) => {
this.tracker.trackAction('controller-events', 'success', 'file.publish', 1);
dialog.close();
SilexNotification.alert('Publication', msg, () => {});
})
.catch((msg) => {
dialog.close();
this.publishError(msg);
});
}
}
});
} else {
this.tracker.trackAction(
'controller-events', 'cancel', 'file.publish', 0);
}
})
.catch((msg) => this.publishError(msg));
}
doPublish(
publicationOptions: PublicationOptions,
cbk: (p1: string, p2: string, p3: PublicationOptions) =>
any) {
const publicationPath = publicationOptions.publicationPath;
const provider = publicationOptions.provider;
// get info about the website file
const file = this.model.file.getFileInfo();
const isTemplate = this.model.file.isTemplate;
// save new path when needed and get publication path
if (publicationPath) {
this.model.head.setPublicationPath(publicationPath);
}
const folder = this.model.head.getPublicationPath();
// the file must be saved somewhere because all URLs are made relative
if (!folder) {
this.view.settingsDialog.open(
() => {},
// here the panel was closed
'publish-pane');
this.view.workspace.redraw(this.view);
cbk(null,
'I do not know where to publish your site.' +
'Select a folder in the settings pannel and do "publish" again.' +
'\nNow I will open the publish settings.',
null);
} else {
if (!file || isTemplate) {
console.error('The file must be saved before I can publish it.');
cbk(null, 'The file must be saved before I can publish it.', null);
} else {
if (!provider) {
const providerName = this.model.head.getHostingProvider();
if (!providerName) {
throw new Error(
'I need a hosting provider name for this website. And none is configured.');
} else {
SilexTasks.getInstance().hosting((hosting) => {
const storedProvider: Provider =
hosting.providers.find((p) => p.name === providerName);
if (!storedProvider) {
SilexNotification.alert('Publication', `
<p>Unknown provider ${providerName}.</p>
<p>Is it configured on this servier? Here are the hosting providers I know:
${hosting.providers.map((p) => p.name).join(', ')}</p>
`, () => {});
throw new Error(`
Unknown provider ${providerName}.
Is it configured on this servier? Here are the hosting providers I know: <ul>${hosting.providers
.map((p) => '<li>' + p.name + '</li>')
.join('')}</ul>
`);
}
cbk(null, null, ({
file,
publicationPath: folder,
provider: storedProvider,
} as PublicationOptions));
});
}
} else {
cbk(null, null, ({
file,
publicationPath: folder,
provider,
} as PublicationOptions));
}
}
}
}
}