diff --git a/customize.dist/DecorateToolbar.js b/customize.dist/DecorateToolbar.js index 49a30c79f..023c929e1 100644 --- a/customize.dist/DecorateToolbar.js +++ b/customize.dist/DecorateToolbar.js @@ -10,8 +10,7 @@ define([ var main = function () { var url = window.location.pathname; var isHtml = /\.html/.test(url) || url === '/' || url === ''; - var isPoll = /\/poll\//.test(url); - if (!isHtml && !isPoll) { + if (!isHtml) { Messages._applyTranslation(); return; } diff --git a/customize.dist/fsStore.js b/customize.dist/fsStore.js index 7910a5cf3..81b2a9f05 100644 --- a/customize.dist/fsStore.js +++ b/customize.dist/fsStore.js @@ -86,6 +86,14 @@ define([ cb(); }; + Store.addTemplate = function (href) { + filesOp.addTemplate(href); + }; + + Store.listTemplates = function () { + return filesOp.listTemplates(); + }; + Store.getProxy = function () { return exp; }; @@ -146,11 +154,6 @@ define([ if (!Cryptpad.getUserHash()) { localStorage.FS_hash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys); } - window.patchText = TextPatcher.create({ - realtime: realtime, - logging: true, - }); - }).on('ready', function () { if (!rt.proxy[Cryptpad.storageKey] || !Cryptpad.isArray(rt.proxy[Cryptpad.storageKey])) { var oldStore = Cryptpad.getStore(true); @@ -171,7 +174,7 @@ define([ } return; } - Cryptpad.alert(Messages.common_connectionLost); + //Cryptpad.alert(Messages.common_connectionLost); }); }; diff --git a/customize.dist/main.css b/customize.dist/main.css index b9c517a63..14cf8bf32 100644 --- a/customize.dist/main.css +++ b/customize.dist/main.css @@ -315,6 +315,37 @@ tr { font-family: lato, Helvetica, sans-serif; font-size: 1.02em; } +#loading { + position: fixed; + z-index: 9999; + top: 0px; + bottom: 0px; + left: 0px; + right: 0px; + background: #302B28; + text-align: center; + font-size: 1.5em; +} +#loading .loadingContainer { + margin-top: 50vh; + transform: translateY(-50%); +} +#loading .cryptofist { + margin-left: auto; + margin-right: auto; +} +@media screen and (max-height: 450px) { + #loading .cryptofist { + display: none; + } +} +#loading .spinnerContainer { + position: relative; + height: 100px; +} +#loading .spinnerContainer > div { + height: 100px; +} #main { width: 70vw; margin: auto; diff --git a/customize.dist/main.js b/customize.dist/main.js index 52804a105..af0afa95b 100644 --- a/customize.dist/main.js +++ b/customize.dist/main.js @@ -139,6 +139,8 @@ define([ }); }; + + displayCreateButtons(); Cryptpad.ready(function () { console.log("ready"); @@ -149,7 +151,6 @@ define([ DecorateToolbar.main($('#bottom-bar')); Cryptpad.styleAlerts(); - displayCreateButtons(); refreshTable(); if (Cryptpad.store && Cryptpad.store.change) { Cryptpad.store.change(function (data) { diff --git a/customize.dist/src/cryptpad.less b/customize.dist/src/cryptpad.less index bda4e0c5d..05e033c4c 100644 --- a/customize.dist/src/cryptpad.less +++ b/customize.dist/src/cryptpad.less @@ -137,6 +137,36 @@ p, pre, td, a, table, tr { .lato; } +#loading { + position: fixed; + z-index: 9999; + top: 0px; + bottom: 0px; + left: 0px; + right: 0px; + background: @bg-loading; + text-align: center; + font-size: 1.5em; + .loadingContainer { + margin-top: 50vh; + transform: translateY(-50%); + } + .cryptofist { + margin-left: auto; + margin-right: auto; + @media screen and (max-height: 450px) { + display: none; + } + } + .spinnerContainer { + position: relative; + height: 100px; + > div { + height: 100px; + } + } +} + #main { width: 70vw; margin: auto; diff --git a/customize.dist/src/variables.less b/customize.dist/src/variables.less index c6d555219..f3db72022 100644 --- a/customize.dist/src/variables.less +++ b/customize.dist/src/variables.less @@ -32,3 +32,4 @@ @alertify-input-bg: @base; @alertify-input-fg: @fore; +@bg-loading: @base; diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index 91c840b33..ac72aefc6 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -19,6 +19,10 @@ define(function () { ].join(''); out.common_connectionLost = 'Connexion au serveur perdue'; + out.websocketError = 'Impossible de se connecter au serveur WebSocket...'; + + out.loading = "Chargement..."; + out.error = "Erreur"; out.disconnected = 'Déconnecté'; out.synchronizing = 'Synchronisation'; @@ -190,6 +194,10 @@ define(function () { out.fm_unknownFolderError = "Le dossier sélectionné ou le dernier dossier visité n'existe plus. Ouverture du dossier parent..."; out.fm_contextMenuError = "Impossible d'ouvrir le menu contextuel pour cet élément. Si le problème persiste, essayez de rechercher la page."; out.fm_selectError = "Impossible de sélectionner l'élément ciblé. Si le problème persiste, essayez de recharger la page."; + out.fm_info_root = "Créez ici autant de dossiers que vous le souhaitez pour trier vos fichiers."; + out.fm_info_unsorted = 'Contient tous les documents que vous avez ouvert et qui ne sont pas triés dans "Mes documents" ou déplacés vers la "Corbeille".'; // "My Documents" should match with the "out.fm_rootName" key, and "Trash" with "out.fm_trashName" + out.fm_info_trash = 'Les fichiers supprimés dans la corbeille sont également enlevés de "Tous les fichiers" et il est impossible de les récupérer depuis l\'explorateur de fichiers.'; // Same here for "All files" and "out.fm_filesDataName" + out.fm_info_allFiles = 'Contient tous les fichiers de "Mes documents", "Fichiers non triés" et "Corbeille". Vous ne pouvez pas supprimer ou déplacer des fichiers d\'ici.'; // Same here // File - Context menu out.fc_newfolder = "Nouveau dossier"; out.fc_rename = "Renommer"; @@ -208,6 +216,7 @@ define(function () { out.fo_existingNameError = "Ce nom est déjà utilisé dans ce répertoire. Veuillez en choisir un autre."; out.fo_moveFolderToChildError = "Vous ne pouvez pas déplacer un dossier dans un de ses descendants"; out.fo_unableToRestore = "Impossible de restaurer ce fichier à son emplacement d'origine. Vous pouvez essayer de le déplacer à un nouvel emplacement."; + out.fo_unavailableName = "Un fichier ou dossier avec le même nom existe déjà au nouvel emplacement. Renommez cet élément avant d'essayer à nouveau."; // index.html diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index 4ed01d108..5a2d977df 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -23,6 +23,9 @@ define(function () { out.common_connectionLost = 'Server Connection Lost'; out.websocketError = 'Unable to connect to the websocket server...'; + out.loading = "Loading..."; + out.error = "Error"; + out.disconnected = 'Disconnected'; out.synchronizing = 'Synchronizing'; out.reconnecting = 'Reconnecting...'; @@ -169,6 +172,7 @@ define(function () { out.fm_trashName = "Trash"; out.fm_unsortedName = "Unsorted files"; out.fm_filesDataName = "All files"; + out.fm_templateName = "Templates"; out.fm_newFolder = "New folder"; out.fm_newFolderButton = "NEW FOLDER"; out.fm_folderName = "Folder name"; @@ -189,6 +193,10 @@ define(function () { out.fm_unknownFolderError = "The selected or last visited directory no longer exist. Opening the parent folder..."; out.fm_contextMenuError = "Unable to open the context menu for that element. If the problem persist, try to reload the page."; out.fm_selectError = "Unable to select the targetted element. If the problem persist, try to reload the page."; + out.fm_info_root = "Create as many nested folders here as you want to sort your files."; + out.fm_info_unsorted = 'Contains all the files you\'ve visited that are not yet sorted in "My Documents" or moved to the "Trash".'; // "My Documents" should match with the "out.fm_rootName" key, and "Trash" with "out.fm_trashName" + out.fm_info_trash = 'Files deleted from the trash are also removed from "All files" and it is impossible to recover them from the file manager.'; // Same here for "All files" and "out.fm_filesDataName" + out.fm_info_allFiles = 'Contains all the files from "My Documents", "Unsorted" and "Trash". You can\'t move or remove files from here.'; // Same here // File - Context menu out.fc_newfolder = "New folder"; out.fc_rename = "Rename"; @@ -207,6 +215,7 @@ define(function () { out.fo_existingNameError = "Name already used in that directory. Please choose another one."; out.fo_moveFolderToChildError = "You can't move a folder into one of its descendants"; out.fo_unableToRestore = "Unable to restore that file to its original location. You can try to move it to a new location."; + out.fo_unavailableName = "A file or a folder with the same name already exist at the new location. Rename the element and try again."; // login out.login_login = "log in"; diff --git a/www/code/main.js b/www/code/main.js index 54e166fed..1f22b4e92 100644 --- a/www/code/main.js +++ b/www/code/main.js @@ -21,12 +21,10 @@ define([ var module = window.APP = { Cryptpad: Cryptpad, - spinner: Cryptpad.spinner(document.body), }; Cryptpad.styleAlerts(); - - module.spinner.show(); + Cryptpad.addLoadingScreen(); var ifrw = module.ifrw = $('#pad-iframe')[0].contentWindow; var stringify = function (obj) { @@ -43,8 +41,7 @@ define([ } var onConnectError = function (info) { - module.spinner.hide(); - Cryptpad.alert(Messages.websocketError); + Cryptpad.errorLoadingScreen(Messages.websocketError); }; var andThen = function (CMeditor) { @@ -565,7 +562,7 @@ define([ }); } - $(module.spinner.get().el).fadeOut(750); + Cryptpad.removeLoadingScreen(); setEditable(true); initializing = false; //Cryptpad.log("Your document is ready"); diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index f02e1747f..481e33bd1 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -409,6 +409,21 @@ define([ return localStorage[attr]; }; + // STORAGE - TEMPLATES + var listTemplates = common.listTemplates = function (type) { + var allTemplates = getStore().listTemplates(); + if (!type) { return allTemplates; } + + var templates = allTemplates.filter(function (f) { + var parsed = parsePadUrl(f.href); + return parsed.type === type; + }); + return templates; + }; + var addTemplate = common.addTemplate = function (href) { + getStore().addTemplate(href); + }; + // STORAGE /* fetch and migrate your pad history from localStorage */ @@ -651,6 +666,26 @@ define([ }); }; + var LOADING = 'loading'; + common.addLoadingScreen = function () { + var $loading = $('
').text(Messages.loading); + $container.append($spinner).append($text); + $loading.append($container); + $('body').append($loading); + }; + common.removeLoadingScreen = function () { + $('#' + LOADING).fadeOut(750); + }; + common.errorLoadingScreen = function (error) { + $('.spinnerContainer').hide(); + $('#' + LOADING).find('p').text(error || Messages.error); + }; + /* * Saving files */ @@ -982,17 +1017,17 @@ define([ $(parent).append($target); var opts = { - lines: 9, // The number of lines to draw - length: 12, // The length of each line - width: 11, // The line thickness - radius: 20, // The radius of the inner circle + lines: 20, // The number of lines to draw + length: 5, // The length of each line + width: 2, // The line thickness + radius: 15, // The radius of the inner circle scale: 2, // Scales overall size of the spinner corners: 1, // Corner roundness (0..1) - color: '#777', // #rgb or #rrggbb or array of colors + color: '#ddd', // #rgb or #rrggbb or array of colors opacity: 0.3, // Opacity of the lines rotate: 31, // The rotation offset direction: 1, // 1: clockwise, -1: counterclockwise - speed: 0.9, // Rounds per second + speed: 1, // Rounds per second trail: 49, // Afterglow percentage fps: 20, // Frames per second when using setTimeout() as a fallback for CSS zIndex: 2e9, // The z-index (defaults to 2000000000) @@ -1001,7 +1036,8 @@ define([ left: '50%', // Left position relative to parent shadow: false, // Whether to render a shadow hwaccel: false, // Whether to use hardware acceleration - position: 'absolute', // Element positioning + position: 'relative', // Element positioning + height: '100px' }; var spinner = new Spinner(opts).spin($target[0]); diff --git a/www/file/file.css b/www/file/file.css index 72caad18e..1d2f7e1ec 100644 --- a/www/file/file.css +++ b/www/file/file.css @@ -97,7 +97,7 @@ li { text-decoration: underline; } -#tree #trashTree, #tree #unsortedTree, #tree #allfilesTree { +#tree #trashTree, #tree #unsortedTree, #tree #templateTree, #tree #allfilesTree { margin-top: 2em; } @@ -186,6 +186,20 @@ li { padding-left: 10px; } +#content .info-box { + margin: 0px auto; + padding: 5px; + background: #ddddff; + border: 1px solid #bbb; + border-radius: 5px; + margin-bottom: 10px; +} +#content .info-box span { + cursor: pointer; + margin-left: 10px; + float: right; +} + .topButtonContainer { border: 1px solid #ccc; float: right; @@ -249,13 +263,10 @@ li { flex: 1; } -#content .list li.file-header { - margin-top: 20px; -} - #content .list li.header { cursor: default; color: #008; + margin-top: 10px; } #content .list li.header .element span:not(.fa) { border-right: 1px solid #CCC; diff --git a/www/file/fileObject.js b/www/file/fileObject.js index 2a339b9cc..df1f80169 100644 --- a/www/file/fileObject.js +++ b/www/file/fileObject.js @@ -9,6 +9,7 @@ define([ var UNSORTED = "unsorted"; var FILES_DATA = "filesData"; var TRASH = "trash"; + var TEMPLATE = "template"; var NEW_FOLDER_NAME = Messages.fm_newFolder; var init = module.init = function (files, config) { @@ -46,6 +47,12 @@ define([ var isPathInUnsorted = exp.isPathInUnsorted = function (path) { return path[0] && path[0] === UNSORTED; }; + var isPathInTemplate = exp.isPathInTemplate = function (path) { + return path[0] && path[0] === TEMPLATE; + }; + var isPathInHrefArray = exp.isPathInHrefArray = function (path) { + return isPathInUnsorted(path) || isPathInTemplate(path); + }; var isPathInTrash = exp.isPathInTrash = function (path) { return path[0] && path[0] === TRASH; }; @@ -162,6 +169,13 @@ define([ return files[UNSORTED].slice(); }; + var getTemplateFiles = exp.getTemplateFiles = function () { + if (!files[TEMPLATE]) { + files[TEMPLATE] = []; + } + return files[TEMPLATE].slice(); + }; + var getFilesRecursively = function (root, arr) { for (var e in root) { if (isFile(root[e])) { @@ -229,13 +243,15 @@ define([ var checkDeletedFiles = function () { var rootFiles = getRootFiles(); var unsortedFiles = getUnsortedFiles(); + var templateFiles = getTemplateFiles(); var trashFiles = getTrashFiles(); var toRemove = []; files[FILES_DATA].forEach(function (arr) { var f = arr.href; if (rootFiles.indexOf(f) === -1 && unsortedFiles.indexOf(f) === -1 - && trashFiles.indexOf(f) === -1) { + && trashFiles.indexOf(f) === -1 + && templateFiles.indexOf(f) === -1) { toRemove.push(arr); } }); @@ -254,7 +270,7 @@ define([ var parentEl = exp.findElement(files, parentPath); if (path.length === 4 && path[0] === TRASH) { files[TRASH][path[1]].splice(path[2], 1); - } else if (path[0] === UNSORTED) { + } else if (path[0] === UNSORTED) { //TODO || === TEMPLATE parentEl.splice(key, 1); } else { parentEl[key] = undefined; @@ -264,6 +280,7 @@ define([ }; // Find an element in a object following a path, resursively + // NOTE: it is always used with an absolute path and root === files in our code var findElement = exp.findElement = function (root, pathInput) { if (!pathInput) { error("Invalid path:\n", pathInput, "\nin root\n", root); @@ -279,6 +296,7 @@ define([ return findElement(root[key], path); }; + // Get the object {element: element, path: [path]} from a trash root path var getTrashElementData = exp.getTrashElementData = function (trashPath) { if (!isInTrashRoot) { debug("Called getTrashElementData on a element not in trash root: ", trashPath); @@ -289,6 +307,7 @@ define([ return findElement(files, parentPath); }; + // Get data from AllFiles (Cryptpad_RECENTPADS) var getFileData = exp.getFileData = function (file) { if (!file) { return; } var res; @@ -328,6 +347,7 @@ define([ }; // Move to trash + // TODO: rename the function var removeElement = exp.removeElement = function (path, cb, keepOld) { if (!path || path.length < 2 || path[0] === TRASH) { debug("Calling removeElement from a wrong path: ", path); @@ -335,7 +355,7 @@ define([ } var element = findElement(files, path); var key = path[path.length - 1]; - var name = isPathInUnsorted(path) ? getTitle(element) : key; + var name = isPathInHrefArray(path) ? getTitle(element) : key; var parentPath = path.slice(); parentPath.pop(); pushToTrash(name, element, parentPath); @@ -353,19 +373,21 @@ define([ var newParent = findElement(files, newParentPath); + // Never move a folder in one of its children if (isFolder(element) && isSubpath(newParentPath, elementPath)) { log(Messages.fo_moveFolderToChildError); return; } - if (isPathInUnsorted(newParentPath)) { + if (isPathInHrefArray(newParentPath)) { if (isFolder(element)) { - log(Messages.fo_moveUnsortedError); + log(Messages.fo_moveUnsortedError); //TODO or template return; } else { - if (isPathInUnsorted(elementPath)) { return; } - if (files[UNSORTED].indexOf(element) === -1) { - files[UNSORTED].push(element); + if (elementPath[0] === newParentPath[0]) { return; } + var fileRoot = newParentPath[0]; + if (files[fileRoot].indexOf(element) === -1) { + files[fileRoot].push(element); } if (!keepOld) { deleteFromObject(elementPath); } if(cb) { cb(); } @@ -375,7 +397,7 @@ define([ var name; - if (isPathInUnsorted(elementPath)) { + if (isPathInHrefArray(elementPath)) { name = getTitle(element); } else if (isInTrashRoot(elementPath)) { // Element from the trash root: elementPath = [TRASH, "{dirName}", 0, 'element'] @@ -386,7 +408,7 @@ define([ var newName = !isPathInRoot(elementPath) ? getAvailableName(newParent, name) : name; if (typeof(newParent[newName]) !== "undefined") { - log("A file with the same name already exist at the new location. Rename the file and try again."); + log(Messages.fo_unavailableName); return; } newParent[newName] = element; @@ -397,13 +419,16 @@ define([ // "Unsorted" is an array of href: we can't move several of them using "moveElement" in a // loop because moveElement removes the href from the array and it changes the path for all // the other elements. We have to move them all and then remove them from unsorted - var moveUnsortedElements = exp.moveUnsortedElements = function (paths, newParentPath, cb) { + var moveHrefArrayElements = exp.moveHrefArrayElements = function (paths, newParentPath, cb) { if (!paths || paths.length === 0) { return; } - if (isPathInUnsorted(newParentPath)) { return; } + //if (isPathInHrefArray(newParentPath)) { return; } var elements = {}; // Get the elements paths.forEach(function (p) { - if (!isPathInUnsorted(p)) { return; } + // Here we move only files from array categories (unsorted, template...) + if (!isPathInHrefArray(p)) { return; } + // And we check that we don't want to move to the same location + if (p[0] === newParentPath[0]) { return; } var el = findElement(files, p); if (el) { elements[el] = p; } }); @@ -413,22 +438,21 @@ define([ }); // Remove the elements from their old location Object.keys(elements).forEach(function (el) { - var idx = files[UNSORTED].indexOf(el); + var fileRoot = elements[el][0]; + var idx = files[fileRoot].indexOf(el); if (idx !== -1) { - files[UNSORTED].splice(idx, 1); + files[fileRoot].splice(idx, 1); } }); if (cb) { cb(); } }; var moveElements = exp.moveElements = function (paths, newParentPath, cb) { - var unsortedPaths = paths.filter(function (p) { - return p[0] === UNSORTED; - }); - moveUnsortedElements(unsortedPaths, newParentPath); + var unsortedPaths = paths.filter(isPathInHrefArray); + moveHrefArrayElements(unsortedPaths, newParentPath); // Copy the elements to their new location paths.forEach(function (p) { - if (isPathInUnsorted(p)) { return; } + if (isPathInHrefArray(p)) { return; } moveElement(p, newParentPath, null); }); if(cb) { cb(); } @@ -471,12 +495,13 @@ define([ var element = findElement(files, path); var parentEl = getTrashElementData(path); var newPath = parentEl.path; - if (isPathInUnsorted(newPath)) { - if (files[UNSORTED].indexOf(element) === -1) { - files[UNSORTED].push(element); - removeFromTrashArray(parentEl, path[1]); - cb(); + if (isPathInHrefArray(newPath)) { + var fileRoot = newPath[0]; + if (files[fileRoot].indexOf(element) === -1) { + files[fileRoot].push(element); } + removeFromTrashArray(parentEl, path[1]); + cb(); return; } // Find the new parent element @@ -523,6 +548,7 @@ define([ var emptyTrash = exp.emptyTrash = function (cb) { files[TRASH] = {}; + checkDeletedFiles(); if(cb) { cb(); } }; @@ -569,7 +595,12 @@ define([ var unsortedFiles = getUnsortedFiles(); var rootFiles = getRootFiles(); var trashFiles = getTrashFiles(); - if (path && name) { + var templateFiles = getTemplateFiles(); + if (path && isPathInHrefArray(path)) { + var parentEl = findElement(files, newPath); + parentEl.push(href); + } + else if (path && name) { var newPath = decodeURIComponent(path).split(','); var parentEl = findElement(files, newPath); if (parentEl) { @@ -578,11 +609,38 @@ define([ return; } } - if (unsortedFiles.indexOf(href) === -1 && rootFiles.indexOf(href) === -1 && trashFiles.indexOf(href) === -1) { + if (unsortedFiles.indexOf(href) === -1 && rootFiles.indexOf(href) === -1&& templateFiles.indexOf(href) === -1 && trashFiles.indexOf(href) === -1) { files[UNSORTED].push(href); } }; + // addTemplate is called when we want to add a new pad, never visited, to the templates list + // first, we must add it to FILES_DATA, so the input has to be an fileDAta object + var addTemplate = exp.addTemplate = function (fileData) { + if (typeof fileData !== "object" || !fileData.href || !fileData.title) { return; } + + var href = fileData.href; + var test = files[FILES_DATA].some(function (o) { + o.href === href; + }); + if (!test) { + files[FILES_DATA].push(fileData); + } + if (files[TEMPLATE].indexOf(href) === -1) { + files[TEMPLATE].push(href); + } + }; + + var listTemplates = exp.listTemplates = function (type) { + var templateFiles = getTemplateFiles(); + var res = []; + templateFiles.forEach(function (f) { + var data = getFileData(f); + res.push(JSON.parse(JSON.stringify(data))); + }); + return res; + }; + var uniq = function (a) { var seen = {}; return a.filter(function(item) { @@ -592,7 +650,7 @@ define([ var fixFiles = exp.fixFiles = function () { // Explore the tree and check that everything is correct: - // * 'root', 'trash' and 'filesData' exist and are objects + // * 'root', 'trash', 'unsorted' and 'filesData' exist and are objects // * ROOT: Folders are objects, files are href // * TRASH: Trash root contains only arrays, each element of the array is an object {element:.., path:..} // * FILES_DATA: - Data (title, cdate, adte) are stored in filesData. filesData contains only href keys linking to object with title, cdate, adate. @@ -601,16 +659,13 @@ define([ // * UNSORTED: Contains only files (href), and does not contains files that are in ROOT debug("Cleaning file system..."); - // Create a backup - if (typeof(localStorage.oldFileSystem) === "undefined") { - localStorage.oldFileSystem = '[]'; - } var before = JSON.stringify(files); if (typeof(files[ROOT]) !== "object") { debug("ROOT was not an object"); files[ROOT] = {}; } if (typeof(files[TRASH]) !== "object") { debug("TRASH was not an object"); files[TRASH] = {}; } if (!$.isArray(files[FILES_DATA])) { debug("FILES_DATA was not an array"); files[FILES_DATA] = []; } if (!$.isArray(files[UNSORTED])) { debug("UNSORTED was not an array"); files[UNSORTED] = []; } + if (!$.isArray(files[TEMPLATE])) { debug("TEMPLATE was not an array"); files[TEMPLATE] = []; } var fixRoot = function (element) { for (var el in element) { @@ -650,16 +705,42 @@ define([ var fixUnsorted = function (us) { var rootFiles = getRootFiles().slice(); + var templateFiles = getTemplateFiles(); var toClean = []; us.forEach(function (el, idx) { - if (!isFile(el) || rootFiles.indexOf(el) !== -1) { + if (!isFile(el) || rootFiles.indexOf(el) !== -1 || templateFiles.indexOf(el) !== -1) { toClean.push(idx); } }); + toClean.forEach(function (el) { + var idx = us.indexOf(el); + if (idx !== -1) { + us.splice(idx, 1); + } + }); }; files[UNSORTED] = uniq(files[UNSORTED]); fixUnsorted(files[UNSORTED]); + var fixTemplate = function (us) { + var rootFiles = getRootFiles().slice(); + var unsortedFiles = getUnsortedFiles(); + var toClean = []; + us.forEach(function (el, idx) { + if (!isFile(el) || rootFiles.indexOf(el) !== -1 || unsortedFiles.indexOf(el) !== -1) { + toClean.push(idx); + } + }); + toClean.forEach(function (el) { + var idx = us.indexOf(el); + if (idx !== -1) { + us.splice(idx, 1); + } + }); + }; + files[TEMPLATE] = uniq(files[TEMPLATE]); + fixUnsorted(files[TEMPLATE]); + var fixFilesData = function (fd) { var rootFiles = getRootFiles(); var unsortedFiles = getUnsortedFiles(); diff --git a/www/file/main.js b/www/file/main.js index 73066590a..237c4c5c7 100644 --- a/www/file/main.js +++ b/www/file/main.js @@ -18,9 +18,15 @@ define([ var $iframe = $('#pad-iframe').contents(); var ifrw = $('#pad-iframe')[0].contentWindow; + //Cryptpad.addLoadingScreen(); + var onConnectError = function (info) { + Cryptpad.errorLoadingScreen(Messages.websocketError); + }; + var APP = window.APP = { $bar: $iframe.find('#toolbar'), - editable: false + editable: false, + Cryptpad: Cryptpad }; var ROOT = "root"; @@ -29,6 +35,8 @@ define([ var UNSORTED_NAME = Messages.fm_unsortedName; var FILES_DATA = Cryptpad.storageKey; var FILES_DATA_NAME = Messages.fm_filesDataName; + var TEMPLATE = "template"; + var TEMPLATE_NAME = Messages.fm_templateName; var TRASH = "trash"; var TRASH_NAME = Messages.fm_trashName; var LOCALSTORAGE_LAST = "cryptpad-file-lastOpened"; @@ -48,19 +56,13 @@ define([ console.error.apply(console, arguments); }; var log = config.log = Cryptpad.log; - var DEBUG_LS = APP.DEBUG_LS = { - resetLocalStorage : function () { - delete localStorage[LOCALSTORAGE_OPENED]; - delete localStorage[LOCALSTORAGE_LAST]; - } - }; var getLastOpenedFolder = function () { var path; try { - path = localStorage[LOCALSTORAGE_LAST] ? JSON.parse(localStorage[LOCALSTORAGE_LAST]) : [ROOT]; + path = localStorage[LOCALSTORAGE_LAST] ? JSON.parse(localStorage[LOCALSTORAGE_LAST]) : [UNSORTED]; } catch (e) { - path = [ROOT]; + path = [UNSORTED]; } return path; }; @@ -147,7 +149,9 @@ define([ // TOOLBAR var getLastName = function (cb) { - cb(null, files['cryptpad.username'] || ''); + Cryptpad.getAttribute('username', function (err, userName) { + cb(err, userName || ''); + }); }; var setName = APP.setName = function (newName) { @@ -157,11 +161,16 @@ define([ myUserNameTemp = myUserNameTemp.substr(0, 32); } var myUserName = myUserNameTemp; - files['cryptpad.username'] = myUserName; - APP.userName.lastName = myUserName; - var $button = APP.$userNameButton; - var $span = $('