diff --git a/customize.dist/messages.js b/customize.dist/messages.js index 7fa088c43..fdbe2ee7e 100755 --- a/customize.dist/messages.js +++ b/customize.dist/messages.js @@ -26,7 +26,8 @@ var getLanguage = messages._getLanguage = function () { var l = getBrowserLanguage(); // Edge returns 'fr-FR' --> transform it to 'fr' and check again return map[l] ? l : - (map[l.split('-')[0]] ? l.split('-')[0] : 'en'); + (map[l.split('-')[0]] ? l.split('-')[0] : + (map[l.split('_')[0]] ? l.split('_')[0] : 'en')); }; var language = getLanguage(); diff --git a/customize.dist/pages.js b/customize.dist/pages.js index 3fd5e63bb..559c16e02 100644 --- a/customize.dist/pages.js +++ b/customize.dist/pages.js @@ -146,7 +146,7 @@ define([ //h('a.nav-item.nav-link', { href: '/what-is-cryptpad.html'}, Msg.topbar_whatIsCryptpad), // Moved the FAQ //h('a.nav-item.nav-link', { href: '/faq.html'}, Msg.faq_link), h('a.nav-item.nav-link', { href: 'https://blog.cryptpad.fr/'}, Msg.blog), - h('a.nav-item.nav-link', { href: '/features.html'}, Msg.features), + h('a.nav-item.nav-link', { href: '/features.html'}, Msg.pricing), h('a.nav-item.nav-link', { href: '/privacy.html'}, Msg.privacy), //h('a.nav-item.nav-link', { href: '/contact.html'}, Msg.contact), //h('a.nav-item.nav-link', { href: '/about.html'}, Msg.about), diff --git a/customize.dist/pages/features.js b/customize.dist/pages/features.js index ec6adfa6f..07aed6367 100644 --- a/customize.dist/pages/features.js +++ b/customize.dist/pages/features.js @@ -21,14 +21,14 @@ define([ target: '_blank', rel: 'noopener noreferrer' }, h('button.cp-features-register-button', Msg.features_f_subscribe)); - $(premiumButton).click(function (e) { + /*$(premiumButton).click(function (e) { if (LocalStore.isLoggedIn()) { return; } // Not logged in: go to /login with a redirect to this page e.preventDefault(); e.stopPropagation(); sessionStorage.redirectTo = '/features.html'; window.location.href = '/login/'; - }); + });*/ return h('div#cp-main', [ Pages.infopageTopbar(), h('div.container-fluid.cp_cont_features',[ @@ -43,6 +43,10 @@ define([ h('div.card-body',[ h('h3.text-center',Msg.features_anon) ]), + h('div.card-body.cp-pricing',[ + h('div.text-center', '0€'), + h('div.text-center', Msg.features_noData), + ]), h('ul.list-group.list-group-flush', ['apps', 'core', 'file0', 'cryptdrive0', 'storage0'].map(function (f) { return h('li.list-group-item', [ @@ -61,6 +65,10 @@ define([ h('div.card-body',[ h('h3.text-center',Msg.features_registered) ]), + h('div.card-body.cp-pricing',[ + h('div.text-center', '0€'), + h('div.text-center', Msg.features_noData), + ]), h('ul.list-group.list-group-flush', [ ['anon', 'social', 'file1', 'cryptdrive1', 'devices', 'storage1'].map(function (f) { return h('li.list-group-item', [ @@ -87,6 +95,13 @@ define([ h('div.card-body',[ h('h3.text-center',Msg.features_premium) ]), + h('div.card-body.cp-pricing',[ + h('div.text-center', h('a', { + href: accounts.upgradeURL, + target: '_blank' + }, Msg._getKey('features_pricing', ['5', '10', '15']))), + h('div.text-center', Msg.features_emailRequired), + ]), h('ul.list-group.list-group-flush', [ ['reg', 'storage2', 'support', 'supporter'].map(function (f) { return h('li.list-group-item', [ diff --git a/customize.dist/src/less2/include/fileupload.less b/customize.dist/src/less2/include/fileupload.less index 8871eb6af..ebe93399b 100644 --- a/customize.dist/src/less2/include/fileupload.less +++ b/customize.dist/src/less2/include/fileupload.less @@ -68,7 +68,7 @@ } } .cp-fileupload-table-progress { - min-width: 8em; + min-width: 12em; max-width: 16em; position: relative; text-align: center; diff --git a/customize.dist/src/less2/pages/page-features.less b/customize.dist/src/less2/pages/page-features.less index e5e68e7d7..0268f5869 100644 --- a/customize.dist/src/less2/pages/page-features.less +++ b/customize.dist/src/less2/pages/page-features.less @@ -47,6 +47,12 @@ h3 { margin: 0; } + &.cp-pricing { + div { + font-size: 1.2em; + color: @cryptpad_color_blue; + } + } } } h3 { diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 3b6c294bb..c742da570 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -1501,7 +1501,7 @@ define([ UIElements.getAvatar = function (hash) { return avatars[hash]; }; - UIElements.displayAvatar = function (Common, $container, href, name, cb) { + UIElements.displayAvatar = function (common, $container, href, name, cb) { var displayDefault = function () { var text = getFirstEmojiOrCharacter(name); var $avatar = $('', {'class': 'cp-avatar-default'}).text(text); @@ -1537,12 +1537,14 @@ define([ return; } // No password for avatars + var privateData = common.getMetadataMgr().getPrivateData(); + var origin = privateData.fileHost || privateData.origin; var secret = Hash.getSecrets('file', parsed.hash); if (secret.keys && secret.channel) { var hexFileName = secret.channel; var cryptKey = Hash.encodeBase64(secret.keys && secret.keys.cryptKey); var src = Hash.getBlobPathFromHex(hexFileName); - Common.getFileSize(hexFileName, function (e, data) { + common.getFileSize(hexFileName, function (e, data) { if (e || !data) { displayDefault(); return void console.error(e || "404 avatar"); @@ -1550,9 +1552,9 @@ define([ if (typeof data !== "number") { return void displayDefault(); } if (Util.bytesToMegabytes(data) > 0.5) { return void displayDefault(); } var $img = $('').appendTo($container); - $img.attr('src', src); + $img.attr('src', origin + src); $img.attr('data-crypto-key', 'cryptpad:' + cryptKey); - UIElements.displayMediatagImage(Common, $img, function (err, $image, img) { + UIElements.displayMediatagImage(common, $img, function (err, $image, img) { if (err) { return void console.error(err); } centerImage($img, $image, img); }); @@ -1859,6 +1861,15 @@ define([ content: $userAdminContent.html() }); } + options.push({ + tag: 'a', + attributes: { + 'target': '_blank', + 'href': origin+'/index.html', + 'class': 'fa fa-home' + }, + content: h('span', Messages.homePage) + }); if (padType !== 'drive' || (!accountName && priv.newSharedFolder)) { options.push({ tag: 'a', @@ -1870,6 +1881,7 @@ define([ content: h('span', Messages.login_accessDrive) }); } + options.push({ tag: 'hr' }); // Add the change display name button if not in read only mode if (config.changeNameButtonCls && config.displayChangeName && !AppConfig.disableProfile) { options.push({ @@ -1892,6 +1904,7 @@ define([ content: h('span', Messages.settingsButton) }); } + options.push({ tag: 'hr' }); // Add administration panel link if the user is an admin if (priv.edPublic && Array.isArray(Config.adminKeys) && Config.adminKeys.indexOf(priv.edPublic) !== -1) { options.push({ @@ -1907,6 +1920,16 @@ define([ content: h('span', Messages.supportPage || 'Support') }); } + options.push({ + tag: 'a', + attributes: { + 'target': '_blank', + 'href': origin+'/features.html', + 'class': 'fa fa-star-o' + }, + content: h('span', priv.plan ? Messages.settings_cat_subscription : Messages.pricing) + }); + options.push({ tag: 'hr' }); // Add login or logout button depending on the current status if (accountName) { options.push({ diff --git a/www/common/sframe-common-codemirror.js b/www/common/sframe-common-codemirror.js index f910f12b6..6174e3a4c 100644 --- a/www/common/sframe-common-codemirror.js +++ b/www/common/sframe-common-codemirror.js @@ -416,8 +416,12 @@ define([ "Backspace": function () { var cursor = doc.getCursor(); var line = doc.getLine(cursor.line); - if (line.substring(0, cursor.ch).trim() === "") { editor.execCommand("indentLess"); } - else { editor.execCommand("delCharBefore"); } + var beforeCursor = line.substring(0, cursor.ch); + if (beforeCursor && beforeCursor.trim() === "") { + editor.execCommand("indentLess"); + } else { + editor.execCommand("delCharBefore"); + } }, }); diff --git a/www/common/sframe-common-file.js b/www/common/sframe-common-file.js index 3956c60a6..d79ed758d 100644 --- a/www/common/sframe-common-file.js +++ b/www/common/sframe-common-file.js @@ -301,7 +301,7 @@ define([ ]); $(content).find('#cp-upload-owned').on('change', function () { - var val = Util.isCheked($(content).find('#cp-upload-owned')); + var val = Util.isChecked($(content).find('#cp-upload-owned')); if (val) { $(content).find('#cp-upload-store').prop('checked', true).prop('disabled', true); } else { @@ -533,8 +533,7 @@ define([ createUploader(config.dropArea, config.hoverArea, config.body); - // XXX an X is still displayed when downloading, even though we can't cancel (at the moment) - // XXX implement the abiality to cancel downloads :D + // TODO implement the ability to cancel downloads :D var updateProgressbar = function (file, data, downloadFunction, cb) { if (queue.inProgress) { return; } queue.inProgress = true; @@ -625,10 +624,10 @@ define([ }); */ -/* $row.find('.cp-fileupload-table-cancel') .html('') - .append($cancel); */ + .append(h('span.fa.fa-minus')); + //.append($cancel); }; File.downloadFile = function (fData, cb) { diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index 82c71ace2..c6a56c14d 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -505,7 +505,7 @@ define([ }; var shortcuts = []; - funcs.addShortcuts = function (w) { + funcs.addShortcuts = function (w, isApp) { w = w || window; if (shortcuts.indexOf(w) !== -1) { return; } shortcuts.push(w); @@ -513,7 +513,7 @@ define([ // Ctrl || Meta (mac) if (e.ctrlKey || (navigator.platform === "MacIntel" && e.metaKey)) { // Ctrl+E: New pad modal - if (e.which === 69) { + if (e.which === 69 && isApp) { e.preventDefault(); return void funcs.createNewPadModal(); } @@ -619,22 +619,24 @@ define([ ctx.metadataMgr.onReady(waitFor()); - funcs.addShortcuts(); }).nThen(function () { + var privateData = ctx.metadataMgr.getPrivateData(); + funcs.addShortcuts(window, Boolean(privateData.app)); + try { - var feedback = ctx.metadataMgr.getPrivateData().feedbackAllowed; + var feedback = privateData.feedbackAllowed; Feedback.init(feedback); } catch (e) { Feedback.init(false); } try { - var forbidden = ctx.metadataMgr.getPrivateData().disabledApp; + var forbidden = privateData.disabledApp; if (forbidden) { UI.alert(Messages.disabledApp, function () { funcs.gotoURL('/drive/'); }, {forefront: true}); return; } - var mustLogin = ctx.metadataMgr.getPrivateData().registeredOnly; + var mustLogin = privateData.registeredOnly; if (mustLogin) { UI.alert(Messages.mustLogin, function () { funcs.setLoginRedirect(function () { @@ -648,7 +650,7 @@ define([ } try { - window.CP_DEV_MODE = ctx.metadataMgr.getPrivateData().devMode; + window.CP_DEV_MODE = privateData.devMode; } catch (e) {} ctx.sframeChan.on('EV_LOGOUT', function () { @@ -658,7 +660,7 @@ define([ } }); UI.addLoadingScreen({hideTips: true}); - var origin = ctx.metadataMgr.getPrivateData().origin; + var origin = privateData.origin; var href = origin + "/login/"; var onLogoutMsg = Messages._getKey('onLogout', ['', '']); UI.errorLoadingScreen(onLogoutMsg, true); diff --git a/www/common/translations/messages.de.json b/www/common/translations/messages.de.json index 208363e60..a3380ca72 100644 --- a/www/common/translations/messages.de.json +++ b/www/common/translations/messages.de.json @@ -1124,5 +1124,14 @@ "requestEdit_accepted": "{1} hat dir Bearbeitungsrechte für das Pad {0} gegeben", "requestEdit_sent": "Anfrage gesendet", "uploadFolderButton": "Ordner hochladen", - "properties_unknownUser": "{0} unbekannte(r) Benutzer" + "properties_unknownUser": "{0} unbekannte(r) Benutzer", + "fm_morePads": "Mehr", + "fc_openInCode": "Im Code-Editor öffnen", + "uploadFolder_modal_title": "Optionen für Ordnerupload", + "uploadFolder_modal_filesPassword": "Passwort für Dateien", + "uploadFolder_modal_owner": "Eigene Dateien", + "uploadFolder_modal_forceSave": "Dateien im CryptDrive speichern", + "convertFolderToSF_SFParent": "Dieser Ordner kann an seinem aktuellen Ort nicht einen geteilten Ordner umgewandelt werden. Verschiebe ihn zunächst aus dem übergeordneten geteilten Ordner heraus.", + "convertFolderToSF_SFChildren": "Dieser Ordner kann nicht in einen geteilten Ordner umgewandelt werden, weil er bereits geteilte Ordner enthält. Verschiebe diese geteilten Ordner zunächst an einen anderen Ort.", + "convertFolderToSF_confirm": "Dieser Ordner muss in einen geteilten Ordner umgewandelt werden, damit ihn andere sehen können. Fortfahren?" } diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json index 73a198238..7295f1f39 100644 --- a/www/common/translations/messages.fr.json +++ b/www/common/translations/messages.fr.json @@ -1126,13 +1126,15 @@ "requestEdit_sent": "Demande envoyée", "uploadFolderButton": "Importer un dossier", "properties_unknownUser": "{0} utilisateur(s) inconnu(s)", - "fm_morePads": "Plus de pads", + "fm_morePads": "Plus", "fc_openInCode": "Ouvrir dans l'application Code", "uploadFolder_modal_title": "Options d'importation du dossier", "uploadFolder_modal_filesPassword": "Mot de passe des fichiers", "uploadFolder_modal_owner": "Être propriétaire des fichiers", "uploadFolder_modal_forceSave": "Stocker les fichiers dans votre CryptDrive", - "convertFolderToSF_SFParent": "Impossible de convertir ce dossier en dossier partagé car il se situe à l'interieur d'un autre dossier partagé. Veuillez le déplacer à l'extérieur afin de continuer.", + "convertFolderToSF_SFParent": "Impossible de convertir ce dossier en dossier partagé car il se situe à l'intérieur d'un autre dossier partagé. Veuillez le déplacer à l'extérieur afin de continuer.", "convertFolderToSF_SFChildren": "Impossible de convertir ce dossier en dossier partagé car il contient déjà d'autres dossiers partagés. Veuillez déplacer ces dossiers à l'extérieur afin de continuer.", - "convertFolderToSF_confirm": "Ce dossier va être converti en dossier partagé afin de pouvoir être accessible par d'autres utilisateurs. Continuer ?" + "convertFolderToSF_confirm": "Ce dossier va être converti en dossier partagé afin de pouvoir être accessible par d'autres utilisateurs. Continuer ?", + "pricing": "Tarification", + "homePage": "Page d'accueil" } diff --git a/www/common/translations/messages.json b/www/common/translations/messages.json index 73c6bb8c3..bee205c59 100644 --- a/www/common/translations/messages.json +++ b/www/common/translations/messages.json @@ -322,7 +322,7 @@ "fm_newButtonTitle": "Create a new pad or folder, import a file in the current folder", "fm_newFolder": "New folder", "fm_newFile": "New pad", - "fm_morePads": "More pads", + "fm_morePads": "More", "fm_folder": "Folder", "fm_sharedFolder": "Shared folder", "fm_folderName": "Folder name", @@ -1134,5 +1134,7 @@ "requestEdit_accepted": "{1} granted you edit rights for the pad {0}", "requestEdit_sent": "Request sent", "uploadFolderButton": "Upload folder", - "properties_unknownUser": "{0} unknown user(s)" + "properties_unknownUser": "{0} unknown user(s)", + "pricing": "Pricing", + "homePage": "Home page" } diff --git a/www/file/inner.js b/www/file/inner.js index efbbd46a4..6a78e5f45 100644 --- a/www/file/inner.js +++ b/www/file/inner.js @@ -59,6 +59,7 @@ define([ var secret; var metadataMgr = common.getMetadataMgr(); var priv = metadataMgr.getPrivateData(); + var fileHost = priv.fileHost || priv.origin; if (!priv.filehash) { uploadMode = true; @@ -88,7 +89,7 @@ define([ if (!uploadMode) { var hexFileName = secret.channel; - var src = Hash.getBlobPathFromHex(hexFileName); + var src = fileHost + Hash.getBlobPathFromHex(hexFileName); var key = secret.keys && secret.keys.cryptKey; var cryptKey = Nacl.util.encodeBase64(key); diff --git a/www/profile/app-profile.less b/www/profile/app-profile.less index 852b11421..1284f31c4 100644 --- a/www/profile/app-profile.less +++ b/www/profile/app-profile.less @@ -122,9 +122,13 @@ #cp-app-profile-invite-button { float: right; } - #cp-app-profile-viewprofile-button { + .cp-app-profile-viewprofile-button { margin-bottom: 20px; float: right; + margin-left: 5px; + &> span { + margin-left: 10px; + } } #cp-app-profile-description { position: relative; diff --git a/www/profile/inner.js b/www/profile/inner.js index 75f1022f8..324e918a8 100644 --- a/www/profile/inner.js +++ b/www/profile/inner.js @@ -9,6 +9,7 @@ define([ '/common/common-interface.js', '/common/common-ui-elements.js', '/common/common-realtime.js', + '/common/clipboard.js', '/common/hyperscript.js', '/customize/messages.js', '/customize/application_config.js', @@ -36,6 +37,7 @@ define([ UI, UIElements, Realtime, + Clipboard, h, Messages, AppConfig, @@ -96,15 +98,20 @@ define([ var hash = common.getMetadataMgr().getPrivateData().hashes.viewHash; var url = APP.origin + '/profile/#' + hash; - var $button = $('