/** * 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 please wait. `, () => {}); // 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', `An error occured.
I did not manage to publish the website. ${ message}
`, () => {}); } /** * 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', `Unknown provider ${providerName}.
Is it configured on this servier? Here are the hosting providers I know: ${hosting.providers.map((p) => p.name).join(', ')}
`, () => {}); throw new Error(` Unknown provider ${providerName}. Is it configured on this servier? Here are the hosting providers I know: