From aa30ec2b03d8c4da01b0bc495c1d038c80a83293 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 7 Sep 2021 17:48:07 +0200 Subject: [PATCH 01/17] Translated using Weblate (French) Currently translated at 100.0% (1424 of 1424 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/fr/ --- www/common/translations/messages.fr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json index d3125fb13..c7831f922 100644 --- a/www/common/translations/messages.fr.json +++ b/www/common/translations/messages.fr.json @@ -1281,8 +1281,8 @@ "form_newOption": "Nouvelle option", "form_defaultItem": "Objet {0}", "form_defaultOption": "Option {0}", - "form_anonymous_off": "Bloquées", - "form_anonymous_on": "Autorisées", + "form_anonymous_off": "Bloqué", + "form_anonymous_on": "Autorisé", "form_anonymous": "Accès visiteur (non connecté)", "form_willClose": "Ce formulaire fermera le {0}", "form_isClosed": "Ce formulaire a été fermé le {0}", From 62b111df5aff6cbbd7ef77bfb682b24502c030af Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 7 Sep 2021 17:48:07 +0200 Subject: [PATCH 02/17] Translated using Weblate (German) Currently translated at 98.0% (1396 of 1424 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/de/ --- www/common/translations/messages.de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/translations/messages.de.json b/www/common/translations/messages.de.json index 3d37d8b8c..f91af10a4 100644 --- a/www/common/translations/messages.de.json +++ b/www/common/translations/messages.de.json @@ -1323,7 +1323,7 @@ "form_answerName": "Antwort von {0} am {1}", "form_answerAnonymous": "Anonyme Antwort am {0}", "form_anonymousBox": "Anonym antworten", - "form_anonymous_blocked": "Anonyme Antworten sind in diesem Formular nicht erlaubt. Du musst dich einloggen oder registrieren, um Antworten abzusenden.", + "form_anonymous_blocked": "Antworten von Gästen sind in diesem Formular nicht erlaubt. Du musst dich einloggen oder registrieren, um Antworten abzusenden.", "form_anonymous_off": "Blockiert", "form_invalidWarning": "Es gibt fehlerhafte Antworten:", "form_notAnswered": "{0} leere Antworten", From 0699e21a51b063e0ecc6f8ea32c93c949127e907 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 8 Sep 2021 10:03:35 +0200 Subject: [PATCH 03/17] Translated using Weblate (German) Currently translated at 100.0% (1424 of 1424 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/de/ --- www/common/translations/messages.de.json | 30 +++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.de.json b/www/common/translations/messages.de.json index f91af10a4..e2e1a6805 100644 --- a/www/common/translations/messages.de.json +++ b/www/common/translations/messages.de.json @@ -1396,5 +1396,33 @@ "upload_addOptionalAlt": "Beschreibungstext hinzufügen (optional)", "toolbar_expand": "Werkzeugleiste ausklappen", "toolbar_collapse": "Werkzeugleiste einklappen", - "profile_defaultAlt": "Standard-Profilbild" + "profile_defaultAlt": "Standard-Profilbild", + "form_required_on": "Erforderlich", + "form_authAnswer": "Dieses Formular kann nicht anonym beantwortet werden", + "form_type_section": "Bedingter Abschnitt", + "form_editable": "Bearbeitung nach Absenden", + "form_addMsg": "Endnachricht hinzufügen", + "form_updateMsg": "Endnachricht bearbeiten", + "form_responseMsg": "Diese Nachricht wird angezeigt, nachdem die Teilnehmer das Formular abgesendet haben.", + "form_required_off": "Optional", + "form_conditional_hint": "Um diesen Abschnitt von Bedingungen abhängig zu machen, füge bitte darüber eine Einfachauswahl- oder Mehrfachauswahl-Frage hinzu", + "form_conditional_addAnd": "UND-Bedingung hinzufügen", + "form_conditional_add": "ODER-Bedingung hinzufügen", + "form_conditional": "Zeige diesen Abschnitt nur, wenn:", + "form_condition_hasnot": "hat nicht", + "form_condition_has": "hat", + "form_condition_isnot": "ist nicht", + "form_condition_is": "ist", + "form_condition_q": "Wähle eine Frage", + "form_condition_v": "Wähle einen Wert", + "form_required_answer": "Antwort: ", + "form_changeTypeConfirm": "Wähle den neuen Fragetyp aus.", + "form_corruptAnswers": "Für dieses Formular gibt es bereits Antworten. Eine Änderung dieses Fragetyps kann dazu führen, dass frühere Antwortdaten ungültig werden.", + "form_makeAnon": "Antworten anonymisieren", + "form_preview": "Vorschau", + "form_requiredWarning": "Die folgenden Fragen müssen beantwortet werden:", + "form_anonAnswer": "Antworten auf dieses Formular sind anonymisiert", + "form_viewAllAnswers": "Alle Antworten anzeigen ({0})", + "form_alreadyAnswered": "Du hast dieses Formular beantwortet am {0}", + "form_template_poll": "Schnelle Terminumfrage" } From ce8344aa45664660c55fe4a81d7d2afbcd494633 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 8 Sep 2021 10:03:35 +0200 Subject: [PATCH 04/17] Translated using Weblate (Japanese) Currently translated at 99.1% (1412 of 1424 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/ --- www/common/translations/messages.ja.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.ja.json b/www/common/translations/messages.ja.json index 8ab53c469..d9004d589 100644 --- a/www/common/translations/messages.ja.json +++ b/www/common/translations/messages.ja.json @@ -1412,5 +1412,8 @@ "form_changeTypeConfirm": "新しい設問の種類を選択してください。", "form_required_answer": "回答: ", "form_requiredWarning": "以下の設問は回答が必須です:", - "form_alreadyAnswered": "このフォームに{0}に回答しました" + "form_alreadyAnswered": "このフォームに{0}に回答しました", + "form_conditional_hint": "このセクションを秘密にするには、その上に選択あるいはチェックボックスの設問を追加してください", + "form_editable": "送信後の編集", + "form_responseMsg": "参加者がフォームを送信すると以下のメッセージが表示されます。" } From 624c9344cc872ddabf7e03ab275c49ca477e98ef Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 8 Sep 2021 11:10:15 +0200 Subject: [PATCH 05/17] Translated using Weblate (Japanese) Currently translated at 99.2% (1413 of 1424 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/ --- www/common/translations/messages.ja.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.ja.json b/www/common/translations/messages.ja.json index d9004d589..98a5126cb 100644 --- a/www/common/translations/messages.ja.json +++ b/www/common/translations/messages.ja.json @@ -1415,5 +1415,6 @@ "form_alreadyAnswered": "このフォームに{0}に回答しました", "form_conditional_hint": "このセクションを秘密にするには、その上に選択あるいはチェックボックスの設問を追加してください", "form_editable": "送信後の編集", - "form_responseMsg": "参加者がフォームを送信すると以下のメッセージが表示されます。" + "form_responseMsg": "参加者がフォームを送信すると以下のメッセージが表示されます。", + "form_type_section": "条件のセクション" } From 95d600e3c6878f17fe5214905aea2b35154d1a5a Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 8 Sep 2021 11:49:49 +0200 Subject: [PATCH 06/17] Translated using Weblate (Japanese) Currently translated at 99.3% (1415 of 1424 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/ --- www/common/translations/messages.ja.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/common/translations/messages.ja.json b/www/common/translations/messages.ja.json index 98a5126cb..9b3676143 100644 --- a/www/common/translations/messages.ja.json +++ b/www/common/translations/messages.ja.json @@ -897,7 +897,7 @@ "mdToolbar_embed": "タイトルを埋め込む", "copyToClipboard": "クリップボードにコピー", "form_anonymousBox": "匿名で回答", - "form_anonymous_blocked": "匿名の回答はブロックされています。回答には ログインもしくは登録が必要です。", + "form_anonymous_blocked": "ゲストの回答はブロックされています。回答には ログインもしくは登録が必要です。", "form_add_item": "項目を追加", "form_type_radio": "選択肢", "form_makePublicWarning": "回答を公開してよろしいですか?これは取り消せません。", @@ -1075,7 +1075,7 @@ "form_add_option": "オプションを追加", "form_newItem": "新しい項目", "form_newOption": "新しいオプション", - "form_anonymous": "匿名の回答", + "form_anonymous": "ゲストアクセス(未ログイン)", "form_removeEnd": "締切日を削除", "form_setEnd": "締切日を設定", "form_isPrivate": "回答は公開されていません", From 2e9a06c94a4937b83e94e2f1ffef7cef87eb75a1 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 9 Sep 2021 10:15:07 +0530 Subject: [PATCH 07/17] update changelog --- CHANGELOG.md | 118 ++++++++++++++++++++------------------------------- 1 file changed, 47 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b03ef9bc5..07c9c54de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,93 +1,69 @@ -# 4.11.0 (WIP) +# 4.11.0 ## Goals +Our main goal for this release was to update our Forms app to address common needs and points of confusion from this summer's survey and the one-on-one interviews conducted with volunteers. Many of these points were limited to forms itself, but some were closely related with some other concepts in the platform and prompted us to make some considerable changes throughout. + ## Update notes -* warning about lack of support for internet explorer - * existing support will get worse over time. please update. - * we only support IE for the home page and related info pages. Apps with complex functionality assume you are using a regularly updated browser. -* this release includes new clientside dependencies. Don't forget to run `bower update` +As of this release we are dropping support for Internet Explorer 11 we learned that even Microsoft stopped supporting it in their own Office 365 platform. This means that we can finally start using some newer browser features that are available in every other modern browser and simplify parts of our code, making it smaller and faster to load for everyone else. + +4.11 doesn't require any manual configuration if you're updating from 4.10, so this should be a fairly simple release. There is a new customization option that is described in the following features section, however, this is entirely optional. To update from 4.10.0 to 4.11.0: 1. Stop your server 2. Get the latest code with git 3. Install the latest dependencies with `bower update` and `npm i` + * this release requires new client-side dependencies, so **don't forget this step** 4. Restart your server 5. Confirm that your instance is passing all the tests included on the `/checkup/` page (on whatever devices you intend to support) ## Features -* unify unregistered/non-registered/anonymous terminology as 'guest' -* support - * prompt users that need support to subscribe - * refactor debugging data generation to easily show users what data is included -* form improvements - * include bar graphs for multiple-answer form questions - * move the tally of empty responses to the top of each question's summary (rather than the bottom) - * conditionally displayed sections depending on the state of previous answers - * nicer participant view without CryptPad toolbar or popups - * response page to with customizable message to thank those that have responded - * more granular form controls and clearer text - * anonymization settings for answers - * optional restriction of a form to registered users only - * real-time form authorship. - * changes are saved as you type, so you no longer need to "save" each question. - * co-author surveys with other users and edit the same question concurrently. - * avoid redrawing active parts of the UI when other authors make a change (datepicker UI, dropdowns, etc.) - * redraw no more than once every 500ms for performance reasons - * preserve current scroll position when other users make changes - * easier access to basic for form authors in the left sidebar: - * preview a form - * copy the participant link - * view existing responses - * more intuitive display of answers - * bar charts throughout, wherever applicable - * options with no answers are still displayed with zero results in the summary rather than not being displayed at all - * options are displayed according to the order of their appearance in the original question, rather than according to the order in which participants chose them - * the number of empty answers is displayed above the scrollable section of each answer's summary rather than at the bottom - * more intuitive controls and default options - * placeholders for text inputs instead of pre-filled fields - * "enter" creates a new field - * "esc" clears an empty field - * easy navigation using the tab key - * convert between related question types: - * radio, checkbox, ranked choices - * multi-radio, multi-check - * more form validation options: - * required questions - * validated question types - * summarize invalid answers at the bottom of the form. jump to the relevant question when clicked. - * CryptPad logo displayed at the bottom of the participant page which links to the home page - * we've pre-filled some options in our "simple scheduling poll" template. -* bar charts on the admin page's 'Performance' tab -* enhancements for guest users and registered users without names or avatars - * two initials for users with a custom name but no avatar (previously one initial, always capitalized) - * animal avatars as defaults instead of indistinguishable initials (A for Anonymous, G for Guest) - * configurable via `AppConfig.emojiAvatars = []` - * authorship data for guests in rich text comments, code editor author data - * emojis in cursor tooltips for guests (rich text, code, slide, kanban) - * emojis in the share and access modals for contacts with empty names -* script to identify unnecessary duplication of translations -* improvements to upload and media-tag UI - * support for adding descriptive text at upload time - * preview of uploaded media in the upload modal -* our link creation UI from 4.9.0 now highlights the URL input field as you type to indicate whether the current URL value is valid -* the share menu now makes its primary actions more clear, with explicit text ("copy link" instead of just "copy") on its main buttons, as well as icons that better match button UI on the rest of the platform. -* we're working towards better accessibility for screen readers with better alt-text and `aria-` attributes to suppress descriptions of strictly visual UI features. +* We've changed the platform's default display name from "Anonymous" to "Guest" and have also replaced existing mentions of "Unregistered" or "Non-registered" users with this terminology. + * The term "Anonymous" was only ever intended to convey the classical sense of the word ("without name or attribution") rather than the stricter modern sense "indistinguishable from a meaningfully large set of other individuals". To be clear, this is a change of terminology, not behaviour. To prevent your IP address from being revealed to the host server while using CryptPad the best option has always been, and continues to be [Tor browser](https://www.torproject.org/download/). + * Going forward, if you see "anonymize" in CryptPad (such as in forms), you can take it to mean that extra efforts are being taken to make protocol-level metadata indistinguishable from that of other users, while "Guest" means only that you haven't registered or have removed your display name. +* While we were reconsidering the notion of guest accounts we decided that it would be useful to be able to distinguish one guest from another. We decided to implement this by hooking into the existing system for displaying users' profile pictures by mapping a list of emojis to guests' randomly generated identifiers. + * We chose a list of emojis that we hoped nobody would find objectionable ('🙈 🦀 🐞 🦋 🐬 🐋 🐢 🦉 🦆 🐧 🦡 🦘 🦨 🦦 🦥 🐼 🐻 🦝 🦓 🐄 💮️ 🐙️ 🌸️ 🌻️ 🐝️ 🐐 🦙 🦒 🐘 🦏 🐁 🐹 🐰 🦫 🦔 🐨 🐱 🐺 👺 👹 👽 👾 🤖'), but we realize that cultures and contexts differ widely. As such, we've made this configurable on a per-instance basis. A custom list of emojis can be set in `customize/application_config.js` as an array of single-emoji strings (`AppConfig.emojiAvatars = ['🥦', '🧄', '🍄', '🌶️'];`) or as an empty array if you prefer not to display any emojis (`AppConfig.emojiAvatars = [];`). See [our admin docs](https://docs.cryptpad.fr/en/admin_guide/customization.html#application-config) for more info on customization. + * Users can edit their display name inline in the user list or on their settings page, in which case their avatar will be one or two letters from their name (their first two initials if their name contains at least one space, otherwise the first two letters of their name). + * Once these initial improvements had been made to the user list, the lack of support for emoji avatars in a number of places felt very conspicuous, so we've done our best to implement them consistently across every social aspect of the platform. Default emoji avatars are also displayed in comments in the rich text editor, in authorship data in our code/markdown editor, in tooltips when you hover over the marker for remote users' cursor location, in the "currently editing" indicator for Kanban cards, in the share and access menus, and in the "contacts" app. +* The file upload dialog now includes a preview of the media that you are about to upload (as long as it's something CryptPad is capable of displaying) as well as a text field for describing the media. Descriptive text is added to the file's encrypted metadata and is applied to rendered media as `alt` or `title` attributes wherever applicable. This coincides with a broader effort to improve keyboard navigation and add support for screenreaders. +* The link creation UI from 4.9.0 now highlights the URL input field as you type to indicate whether the current URL value is valid, rather than simply displaying an error when you submit. +* The 'Performance' tab of the admin panel has reused the bar chart UI we added for displaying the results of forms. +* We've written a small script to help us identify translated strings that are consistently duplicated across the four languages into which CryptPad has been fully translated (English, French, German, Japanese). We plan to use this to remove unnecessary strings in an upcoming release and make it easier to translate the platform into new languages. +* The "share" menu now makes its primary actions more clear, with explicit text ("copy link" instead of just "copy") on its main buttons, as well as icons that better match button UI on the rest of the platform. +* Finally, this release introduces our "v2" forms update with many usability enhancements: + * Forms can now include questions which are displayed based on the condition of participants' earlier answers. + * The participant view of forms no longer displays CryptPad's toolbar and popups and instead uses a full-page view. CryptPad's logo is included at the bottom of the page and acts as a link to the home page. + * Form authors can set a custom message to be displayed to participants once they have submitted a response. + * Some more advanced form settings are available for authors, and we've clarified the descriptions of existing options ("Anonymize responses", "Guest access", "Editing after submission"). + * Form authorship supports real-time editing more broadly than before: + * Changes are saved as you type, so you no longer need to manually save each question. + * Multiple authors can edit edit the same question concurrently without overwriting each other's work. + * We avoid redrawing active parts of the UI when other authors make a change, so remote actions won't interfere with your local datepicker, dropdown selections, etc. + * The UI is redrawn no more than once every 500ms for performance reasons. + * We do our best to preserve current scroll position when other users make changes so authors don't accidentally click on the wrong elements. + * Authors have easier access to basic functionality in the left sidebar that allows them to _preview_ a form, copy the participant link, and view existing responses with a single click. + * The form creation presents better default options (placeholders instead of pre-filled fields for text inputs) and offers intuitive controls, such as "enter" to create a new field, "esc" to clear an empty field, and "tab" to navigate with just the keyboard. + * The summary of existing responses is presented more intuitively: + * The tally of empty responses is now displayed at the top of each question's summary rather than the bottom. + * Bar charts are used throughout, wherever applicable. + * Options with no answers are still displayed with zero results in the summary rather than not being displayed at all. + * Options are displayed according to the order of their appearance in the original question, rather than according to the order in which participants chose them. + * Form authors can conveniently change a question's type wherever its content can be automatically converted to a related format (radio, checkbox, ranked choices). + * There are more options for form validation, such as required questions and new types of questions with automatic validation. Invalid answers are summarized at the bottom of the form. Clicking summaries jumps to the relevant question. + * CryptPad logo is included at the bottom of the participant page and links to the home page so that partipants can create their own forms or learn more about how data is encrypted. + * We now pre-fill some options in our "simple scheduling poll" template, suggesting some basic options for the upcoming week and better indicating how the poll is intended to be used. + * Lastly, authors can assign color themes to their form for some basic visual customization. ## Bug fixes -* fix empty name fields in various places across the platform where we did not fall back to "anonymous/guest" - * teams - * contacts - * ??? -* clarified a comment in the nginx config about _professional support_ -* handled an edge case in ICS import to calendars where DTEND was not defined (use duration or consider it an "all-day" event -* links shared by contacts could be previewed in a modal when viewing their notification. The color of the previewed link was overridden by some bootstrap styles. we now use a better color. -* better validation for team invite links where badly formed invite content could have triggered a type error. - +* While implementing and testing the display of emojis as avatars for guests we found several instances (in teams, chat, and the contacts app) where the UI did not fall back to the default display name. +* We've clarified a comment in our example NGINX file which recommended that admins contact us if they are using CryptPad in a production environment. It now indicates that they should do so _if they require professional support_. +* We now handle an edge case in ICS import to calendars where DTEND was not defined. When a duration is specified we calculate the end of the event relative to the provided start time, and otherwise consider it a "full-day" event as per the ICS specification. +* Users can share links directly with contacts, but we noticed that the color of the previewed link was overridden by some styles from bootstrap, resulting in very low contrast. We now use a standard CryptPad color which is clearly legible in both light and dark mode. +* Finally, we've applied some stricter validation to the encrypted content of team invite links which could have previously resulted in type errors. # 4.10.0 From 8390c5b24498a9220ed5a1f2ce5db9a988def010 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 9 Sep 2021 10:37:21 +0530 Subject: [PATCH 08/17] disable autocomplete for upload alt text --- www/common/sframe-common-file.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/sframe-common-file.js b/www/common/sframe-common-file.js index facd27f22..33d46caf6 100644 --- a/www/common/sframe-common-file.js +++ b/www/common/sframe-common-file.js @@ -330,7 +330,7 @@ define([ h('input#cp-upload-name', {type: 'text', placeholder: defaultFileName, value: defaultFileName}), h('label', {for: 'cp-upload-alt'}, Messages.upload_addOptionalAlt), - h('input#cp-upload-alt', {type: 'text', placeholder: Messages.upload_modal_alt}), + h('input#cp-upload-alt', {type: 'text', placeholder: Messages.upload_modal_alt, autocomplete: 'off'}), h('label', {for: 'cp-upload-password'}, Messages.addOptionalPassword), UI.passwordInput({id: 'cp-upload-password'}), From 8f0312833c949e593f672dc92d5e5dd04f9727c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Benqu=C3=A9?= Date: Thu, 9 Sep 2021 09:29:00 +0100 Subject: [PATCH 09/17] Fix typos in release notes --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07c9c54de..8103511f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Goals -Our main goal for this release was to update our Forms app to address common needs and points of confusion from this summer's survey and the one-on-one interviews conducted with volunteers. Many of these points were limited to forms itself, but some were closely related with some other concepts in the platform and prompted us to make some considerable changes throughout. +Our main goal for this release was to update our Forms app to address feedback gathered in the research we conducted over the summer (survey and one-on-one interviews with volunteers). Many of these points were limited to forms itself, but some were closely related with some other concepts in the platform and prompted us to make some considerable changes throughout. ## Update notes @@ -28,7 +28,7 @@ To update from 4.10.0 to 4.11.0: * We chose a list of emojis that we hoped nobody would find objectionable ('🙈 🦀 🐞 🦋 🐬 🐋 🐢 🦉 🦆 🐧 🦡 🦘 🦨 🦦 🦥 🐼 🐻 🦝 🦓 🐄 💮️ 🐙️ 🌸️ 🌻️ 🐝️ 🐐 🦙 🦒 🐘 🦏 🐁 🐹 🐰 🦫 🦔 🐨 🐱 🐺 👺 👹 👽 👾 🤖'), but we realize that cultures and contexts differ widely. As such, we've made this configurable on a per-instance basis. A custom list of emojis can be set in `customize/application_config.js` as an array of single-emoji strings (`AppConfig.emojiAvatars = ['🥦', '🧄', '🍄', '🌶️'];`) or as an empty array if you prefer not to display any emojis (`AppConfig.emojiAvatars = [];`). See [our admin docs](https://docs.cryptpad.fr/en/admin_guide/customization.html#application-config) for more info on customization. * Users can edit their display name inline in the user list or on their settings page, in which case their avatar will be one or two letters from their name (their first two initials if their name contains at least one space, otherwise the first two letters of their name). * Once these initial improvements had been made to the user list, the lack of support for emoji avatars in a number of places felt very conspicuous, so we've done our best to implement them consistently across every social aspect of the platform. Default emoji avatars are also displayed in comments in the rich text editor, in authorship data in our code/markdown editor, in tooltips when you hover over the marker for remote users' cursor location, in the "currently editing" indicator for Kanban cards, in the share and access menus, and in the "contacts" app. -* The file upload dialog now includes a preview of the media that you are about to upload (as long as it's something CryptPad is capable of displaying) as well as a text field for describing the media. Descriptive text is added to the file's encrypted metadata and is applied to rendered media as `alt` or `title` attributes wherever applicable. This coincides with a broader effort to improve keyboard navigation and add support for screenreaders. +* The file upload dialog now includes a preview of the media that you are about to upload (as long as it's something CryptPad is capable of displaying) as well as a text field for describing the media. Descriptive text is added to the file's encrypted metadata and is applied to rendered media as `alt` or `title` attributes wherever applicable. This coincides with a broader effort to improve keyboard navigation and add support for screen-readers. * The link creation UI from 4.9.0 now highlights the URL input field as you type to indicate whether the current URL value is valid, rather than simply displaying an error when you submit. * The 'Performance' tab of the admin panel has reused the bar chart UI we added for displaying the results of forms. * We've written a small script to help us identify translated strings that are consistently duplicated across the four languages into which CryptPad has been fully translated (English, French, German, Japanese). We plan to use this to remove unnecessary strings in an upcoming release and make it easier to translate the platform into new languages. @@ -41,7 +41,7 @@ To update from 4.10.0 to 4.11.0: * Form authorship supports real-time editing more broadly than before: * Changes are saved as you type, so you no longer need to manually save each question. * Multiple authors can edit edit the same question concurrently without overwriting each other's work. - * We avoid redrawing active parts of the UI when other authors make a change, so remote actions won't interfere with your local datepicker, dropdown selections, etc. + * We avoid redrawing active parts of the UI when other authors make a change, so remote actions won't interfere with your local date-picker, dropdown selections, etc. * The UI is redrawn no more than once every 500ms for performance reasons. * We do our best to preserve current scroll position when other users make changes so authors don't accidentally click on the wrong elements. * Authors have easier access to basic functionality in the left sidebar that allows them to _preview_ a form, copy the participant link, and view existing responses with a single click. @@ -53,7 +53,7 @@ To update from 4.10.0 to 4.11.0: * Options are displayed according to the order of their appearance in the original question, rather than according to the order in which participants chose them. * Form authors can conveniently change a question's type wherever its content can be automatically converted to a related format (radio, checkbox, ranked choices). * There are more options for form validation, such as required questions and new types of questions with automatic validation. Invalid answers are summarized at the bottom of the form. Clicking summaries jumps to the relevant question. - * CryptPad logo is included at the bottom of the participant page and links to the home page so that partipants can create their own forms or learn more about how data is encrypted. + * CryptPad logo is included at the bottom of the participant page and links to the home page so that participants can create their own forms or learn more about how data is encrypted. * We now pre-fill some options in our "simple scheduling poll" template, suggesting some basic options for the upcoming week and better indicating how the poll is intended to be used. * Lastly, authors can assign color themes to their form for some basic visual customization. From 5414fe14de1fb290929b615f076cf93f81cda4aa Mon Sep 17 00:00:00 2001 From: Weblate Date: Sun, 12 Sep 2021 02:18:47 +0200 Subject: [PATCH 10/17] Translated using Weblate (Spanish) Currently translated at 47.4% (675 of 1424 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/es/ Translated using Weblate (Spanish) Currently translated at 46.0% (656 of 1424 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/es/ Translated using Weblate (Spanish) Currently translated at 46.0% (656 of 1424 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/es/ --- www/common/translations/messages.es.json | 59 ++++++++++++++++++------ 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/www/common/translations/messages.es.json b/www/common/translations/messages.es.json index f185ea637..e78d2bcef 100644 --- a/www/common/translations/messages.es.json +++ b/www/common/translations/messages.es.json @@ -20,7 +20,7 @@ "synchronizing": "Sincronizando", "reconnecting": "Reconectando", "readonly": "Sólo lectura", - "anonymous": "Anónimo", + "anonymous": "Invitado", "users": "Usuarios", "viewer": "espectador", "viewers": "espectadores", @@ -124,7 +124,7 @@ "login_invalUser": "Nombre de usuario requerido", "login_invalPass": "Contraseña requerida", "login_unhandledError": "Ha ocurrido un error inesperado :(", - "register_importRecent": "Importar documentos de su sesión no registrada", + "register_importRecent": "Importar documentos de su sesión de invitado", "register_acceptTerms": "Acepto los términos de servicio", "register_passwordsDontMatch": "Las contraseñas no corresponden", "register_mustAcceptTerms": "Tienes que aceptar los términos de servicio", @@ -167,7 +167,7 @@ "settings_import": "Importar", "settings_importConfirm": "¿Seguro que quieres importar tus pads recientes a tu cuenta CryptDrive?", "settings_importDone": "Importación terminada", - "feedback_about": "Si estas leyendo esto, quizás sientas curiosidad por saber por qué CryptPad solicita páginas cuando realizas algunas acciones", + "feedback_about": "Si estas leyendo esto, quizás sientas curiosidad por saber por qué CryptPad solicita páginas cuando realizas ciertas acciones.", "feedback_privacy": "Nos importa tu privacidad, y al mismo tiempo queremos que CryptPad sea muy fácil de usar. Utilizamos este archivo para conocer las funcionalidades que importan a nuestros usuarios, pidiéndolo con un parametro que nos dice qué acción fue realizada.", "feedback_optout": "Si quieres darte de baja, visita tus preferencias, donde podrás activar o desactivar el feedback.", "fm_searchName": "Buscar", @@ -294,7 +294,7 @@ "topbar_whatIsCryptpad": "Qué es CryptPad", "header_homeTitle": "Volver a la página de inicio", "userListButton": "Lista de usuarios", - "userAccountButton": "Tu cuenta", + "userAccountButton": "Menú de usuario", "canvas_saveToDrive": "Guardar esta imagen como archivo en tu CryptDrive", "canvas_currentBrush": "Pincel actual", "fm_viewListButton": "Lista", @@ -306,13 +306,13 @@ "button_newkanban": "Nuevo Kanban", "button_newsheet": "Nueva Hoja", "padNotPinned": "Esta nota expirará luego de 3 meses de inactividad, {0}ingresar{1} o {2}registrarse{3}para conservar.", - "anonymousStoreDisabled": "El webmaster de esta instancia de CryptPad a deshabilitado al almacenamiento para usuarios anónimos. Debes ingresar para poder usar CrytDrive.", + "anonymousStoreDisabled": "El administrador de esta instancia de CryptPad ha deshabilitado al almacenamiento para usuarios anónimos. Debes iniciar sesión para poder usar CryptDrive.", "expiredError": "Este pad ha expirado y ya no está disponible.", - "deletedError": "Esta nota ha sido borrada por su dueño y ya no está disponible.", + "deletedError": "Este documento ha sido borrado y ya no se encuentra disponible.", "inactiveError": "Esta nota ha sido eliminada por inactividad. Presione Esc para crear una nueva nota.", "chainpadError": "Ha ocurrido un error crítico al actualizar su contenido. Esta página esta en modo de sólo lectura, para asegurarse que no perderá su trabajo.
HitEscpara continuar y ver esta nota, o recargar para editar nuevamente.", "invalidHashError": "El documento que has solicitado tiene una URL invalida.", - "errorCopy": " Aún puedes acceder al contenido presionando Esc.
Una vez que cierres esta ventana no te será posible acceder a ella nuevamente.", + "errorCopy": " Aún puedes acceder esta versión en modo lectura persionando Esc.", "errorRedirectToHome": "PresionaEscpara ser redirigido a tu Cryptdrive.", "newVersionError": "Una nueva versión de CryptPad está disponible.
Recargar para usar la nueva versión, o presiona escape para acceder a tu contenido en modo offline.", "deletedFromServer": "Nota borrada", @@ -527,7 +527,7 @@ "whatis_drive": "Organización con CryptDrive", "features": "Caracteristicas", "features_title": "Características", - "features_anon": "No registrado", + "features_anon": "Invitado", "features_registered": "Registrado", "features_premium": "Premium", "features_f_apps": "Acceso a todas las aplicaciones", @@ -539,7 +539,7 @@ "features_f_cryptdrive0_note": "Posibilidad de almacenar los pads visitados en su navegador para poder abrirlos más tarde", "features_f_storage0": "Tiempo de almacenamiento limitado", "features_f_storage0_note": "Los documentos se eliminan después de {0} días de inactividad", - "features_f_anon": "Todas las funciones de usuario anónimo", + "features_f_anon": "Todas las funciones de invitado", "features_f_anon_note": "Con funcionalidad adicional", "features_f_cryptdrive1": "Funcionalidad completa de CryptDrive", "features_f_cryptdrive1_note": "Carpetas, compartir carpetas, plantillas, tareas", @@ -570,7 +570,7 @@ "creation_404": "Este pad ya no existe. Utilice el siguiente formulario para crear un nuevo pad.", "creation_owned1": "Un objeto propiedad puede ser destruido cuando el propietario lo desee. La destrucción de un objeto propio hace que no esté disponible en los CryptDrives de otros usuarios.", "settings_padNotifTitle": "Notificaciones de comentarios", - "password_info": "El bloc que intentas abrir no existe o está protegido con una contraseña. Ingrese la contraseña correcta para acceder a su contenido.", + "password_info": "El documento que intenta abrir no existe o está protegido con una contraseña. Ingrese la contraseña correcta para acceder a su contenido.", "creation_newPadModalDescription": "Haz click en un tipo de documento para crearlo. Tú también puedes presionar Tab para seleccionar el tipo y presiona Enter para confirmar.", "toolbar_degraded": "Actualmente hay más de {0} editores en este documento. La lista de usuarios y el chat están desactivados para mejorar el rendimiento.", "oo_lostEdits": "Lamentablemente, las ediciones recientes no guardadas no se pueden recuperar después de sincronizar el nuevo contenido.", @@ -582,14 +582,14 @@ "properties_addPassword": "Añadir una contraseña", "password_submit": "Enviar", "password_placeholder": "Escriba la contraseña aquí...", - "password_error": "¡No se ha encontrado el pad!
Este error puede ser causado por dos factores: o la contraseña no es válida, o el pad ha sido borrado del servidor.", + "password_error": "No se ha encontrado el documento
Este error puede ser causado por dos factores: la contraseña no es válida o el pad ha sido borrado del servidor.", "creation_passwordValue": "Contraseña", "creation_expiration": "Fecha de vencimiento", "creation_noOwner": "Sin propietario", "creation_owners": "Propietarios", "creation_create": "Crear", "creation_newTemplate": "Nueva plantilla", - "creation_noTemplate": "Sin plantilla", + "creation_noTemplate": "Documento vacío", "creation_password": "Contraseña\n", "creation_expireMonths": "Mes(es)", "creation_expireDays": "Día(s)", @@ -601,8 +601,8 @@ "sharedFolders_forget": "Este bloc sólo se almacena en una carpeta compartida, no puedes moverlo a la papelera. Puedes usar tu CryptDrive si quieres borrarlo.", "share_mediatagCopy": "Copiar mediatag al portapapeles", "share_contactCategory": "Contactos", - "share_linkCopy": "Copiar", - "share_linkOpen": "Previsualizar", + "share_linkCopy": "Copiar enlace", + "share_linkOpen": "Abrir enlace", "share_linkView": "Ver", "share_linkEdit": "Editar", "share_linkAccess": "Permisos de acceso", @@ -646,5 +646,34 @@ "convertFolderToSF_SFParent": "Esta carpeta no puede ser convertida a una carpeta compartida en su actual localización. Mueva la carpeta fuera de la carperta compartida para continuar.", "sharedFolders_share": "Comparte este enlace con otros usuarios registrados para darles accesso a la carpeta compartida. Una vez que ellos/as abran este enlace, la carpeta compartida será añadida a sus CryptDrive.", "sharedFolders_create": "Crear una carpeta compartida", - "sharedFolders_duplicate": "Algunos de los documentos que intentaste mover ya estaban compartidos en la carpeta de destino" + "sharedFolders_duplicate": "Algunos de los documentos que intentaste mover ya estaban compartidos en la carpeta de destino", + "admin_flushCacheTitle": "Vaciar caché HTTP", + "admin_updateLimitDone": "Actualización correcta", + "admin_updateLimitButton": "Actualizar cuotas", + "admin_updateLimitHint": "Forzar una actualización de los límites de almacenamiento del usuario se puede hacer en cualquier momento, pero sólo es necesario en caso de error", + "crowdfunding_button2": "Ayuda a CryptPad", + "autostore_pad": "bloc", + "settings_padOpenLinkTitle": "Abrir links con un click", + "fm_expirablePad": "Expiración: {0}", + "crowdfunding_button": "Apoya a CryptPad", + "autostore_file": "archivo", + "admin_diskUsageButton": "Generar informe", + "admin_diskUsageHint": "Cantidad de almacenamiento gastado por diversos recursos de CryptPad", + "admin_diskUsageTitle": "Almacenamiento usado", + "timeoutError": "Algún error ha cortado la conexión al servidor.
PulsaEsc para recargar la página.", + "contact_email": "Correo electrónico", + "contact_chat": "Chat", + "contact_bug": "Informe de error", + "contact_devHint": "Para sugerencias de funciones, mejoras de usabilidad o para simplemente agradecer.", + "contact_dev": "Contactar a los desarrolladores", + "contact_adminHint": "Para cualquier problema relacionado con su cuenta, límites de almacenamiento o disponibilidad del servicio.\n", + "contact_admin": "Contactar a los administradores", + "footer_tos": "Términos de Servicio", + "footer_legal": "Legal", + "footer_donate": "Donar", + "footer_team": "Colaboradores", + "footer_product": "Producto", + "admin_flushCacheDone": "Vaciado de caché exitoso", + "admin_flushCacheButton": "Vaciar caché", + "admin_flushCacheHint": "Obligar a usuarios a descargar los recursos más nuevos para el cliente (sólo si su servidor está en modo actualizado o “fresh mode”)" } From 4c915f9e5a31e2f90d21897e4b7d1b3b7f07f547 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 22 Sep 2021 14:05:05 +0200 Subject: [PATCH 11/17] Don't show the upload button until we're ready to draw files in the file picker --- www/secureiframe/inner.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/secureiframe/inner.js b/www/secureiframe/inner.js index 18970c47b..0ae5d6ae8 100644 --- a/www/secureiframe/inner.js +++ b/www/secureiframe/inner.js @@ -171,7 +171,7 @@ define([ $block.append(h('p', text)); // Add filter input - var $filter = $(h('p.cp-modal-form')).appendTo($block); + var $filter = $(h('p.cp-modal-form')).hide().appendTo($block); var to; var $input = $('', { type: 'text', @@ -211,6 +211,7 @@ define([ updateContainer = function () { var filter = $input.val().trim(); var todo = function (err, list) { + $filter.show(); if (err) { return void console.error(err); } $container.html(''); Object.keys(list).forEach(function (id) { From ca95af082d5e88bffff8f8bb01e6ed045b8cf3df Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 23 Sep 2021 13:27:34 +0200 Subject: [PATCH 12/17] Fix scrambled data in sheets on reconnect --- www/common/onlyoffice/inner.js | 8 ++++++++ www/common/outer/onlyoffice.js | 2 ++ 2 files changed, 10 insertions(+) diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 591eccc2c..195991db9 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -1156,6 +1156,14 @@ define([ }; var handleChanges = function (obj, send) { + if (APP.history) { + send({ + type: "unSaveLock", + index: ooChannel.cpIndex, + time: +new Date() + }); + return; + } // Add a new entry to the pendingChanges object. // If we can't send the patch within 30s, force a page reload var uid = Util.uid(); diff --git a/www/common/outer/onlyoffice.js b/www/common/outer/onlyoffice.js index b5c3e7ba1..dbde5e199 100644 --- a/www/common/outer/onlyoffice.js +++ b/www/common/outer/onlyoffice.js @@ -87,8 +87,10 @@ define([ chan.wc = wc; chan.sendMsg = function (msg, cb) { cb = cb || function () {}; + var hash = msg.slice(0, 64); wc.bcast(msg).then(function () { chan.history.push(msg); + chan.lastKnownHash = hash; cb(); }, function (err) { cb({error: err}); From 86aad06545c0e0fe1b3c3c8c23cfff1bfe592dab Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 24 Sep 2021 15:53:44 +0200 Subject: [PATCH 13/17] Export form in sheets --- www/common/onlyoffice/inner.js | 75 +++++++++++++++++++++++++++++++++- www/form/export.js | 23 +++++++---- www/form/inner.js | 13 ++++++ 3 files changed, 101 insertions(+), 10 deletions(-) diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 195991db9..0b1ddbde8 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -145,9 +145,13 @@ define([ return metadataMgr.getNetfluxId() + '-' + privateData.clientId; }; + var getWindow = function () { + return window.frames && window.frames[0]; + }; var getEditor = function () { - if (!window.frames || !window.frames[0]) { return; } - return window.frames[0].editor || window.frames[0].editorCell; + var w = getWindow(); + if (!w) { return; } + return w.editor || w.editorCell; }; var setEditable = function (state, force) { @@ -1224,6 +1228,73 @@ define([ }); }; + APP.testArr = [ + ['a','b',1,'d'], + ['e',undefined,'g','h'] + ]; + var makePatch = APP.makePatch = function (arr) { + var w = getWindow(); + if (!w) { return; } + // Define OO classes + var AscCommonExcel = w.AscCommonExcel; + var CellValueData = AscCommonExcel.UndoRedoData_CellValueData; + var CCellValue = AscCommonExcel.CCellValue; + //var History = w.AscCommon.History; + var AscCH = w.AscCH; + var Asc = w.Asc; + var UndoRedoData_CellSimpleData = AscCommonExcel.UndoRedoData_CellSimpleData; + var editor = getEditor(); + + var Id = editor.GetSheet(0).worksheet.Id; + //History.Create_NewPoint(); + var patches = []; + arr.forEach(function (arr2, i) { + arr2.forEach(function (v, j) { + var obj = {}; + if (typeof(v) === "string") { obj.text = v; obj.type = 1; } + else if (typeof(v) === "number") { obj.number = v; obj.type = 0; } + else { return; } + var newValue = new CellValueData(undefined, new CCellValue(obj)); + var nCol = j; + var nRow = i; + var patch = new AscCommonExcel.UndoRedoItemSerializable(AscCommonExcel.g_oUndoRedoCell, AscCH.historyitem_Cell_ChangeValue, Id, + new Asc.Range(nCol, nRow, nCol, nRow), + new UndoRedoData_CellSimpleData(nRow, nCol, undefined, newValue), undefined); + patches.push(patch); + /* + History.Add(AscCommonExcel.g_oUndoRedoCell, AscCH.historyitem_Cell_ChangeValue, Id, + new Asc.Range(nCol, nRow, nCol, nRow), + new UndoRedoData_CellSimpleData(nRow, nCol, undefined, newValue), undefined, true); + */ + }); + }); + var oMemory = new w.AscCommon.CMemory(); + var aRes = []; + patches.forEach(function (item) { + editor.GetSheet(0).worksheet.workbook._SerializeHistoryBase64(oMemory, item, aRes); + }); + + // Make the patch + var msg = { + type: "saveChanges", + changes: parseChanges(JSON.stringify(aRes)), + changesIndex: ooChannel.cpIndex || 0, + locks: getUserLock(getId(), true), + excelAdditionalInfo: null + }; + + // Send the patch + rtChannel.sendMsg(msg, null, function (err, hash) { + if (err) { + return void console.error(err); + } + // Apply it on our side + ooChannel.send(msg); + ooChannel.lastHash = hash; + ooChannel.cpIndex++; + }); + }; + var makeChannel = function () { var msgEv = Util.mkEvent(); diff --git a/www/form/export.js b/www/form/export.js index 4afc4170a..ff4d48dfc 100644 --- a/www/form/export.js +++ b/www/form/export.js @@ -13,9 +13,10 @@ define([ value += '"' + vv + '"'; return value; }; - Export.results = function (content, answers, TYPES) { + Export.results = function (content, answers, TYPES, isArray) { if (!content || !content.form) { return; } var csv = ""; + var array = []; var form = content.form; var questions = [Messages.form_poll_time, Messages.share_formView]; @@ -35,6 +36,7 @@ define([ if (i) { csv += ','; } csv += escapeCSV(v); }); + array.push(questions); Object.keys(answers || {}).forEach(function (key) { var obj = answers[key]; @@ -42,21 +44,26 @@ define([ var time = new Date(obj.time).toISOString(); var msg = obj.msg || {}; var user = msg._userdata || {}; - csv += escapeCSV(time); - csv += ',' + escapeCSV(user.name || Messages.anonymous); + var line = []; + line.push(time); + line.push(user.name || Messages.anonymous); content.order.forEach(function (key) { var type = form[key].type; if (!TYPES[type]) { return; } // Ignore static types if (TYPES[type].exportCSV) { - var res = TYPES[type].exportCSV(msg[key], form[key]).map(function (str) { - return escapeCSV(str); - }).join(','); - csv += ',' + res; + var res = TYPES[type].exportCSV(msg[key], form[key]); + Array.prototype.push.apply(line, res); return; } - csv += ',' + escapeCSV(String(msg[key] || '')); + line.push(String(msg[key] || '')); }); + line.forEach(function (v, i) { + if (i) { csv += ','; } + csv += escapeCSV(v); + }); + array.push(line); }); + if (isArray) { return array; } return csv; }; diff --git a/www/form/inner.js b/www/form/inner.js index cb300facd..c46ccb43a 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -2637,6 +2637,19 @@ define([ }), title); }); + // Export in "sheet" + Messages.form_exportSheet = "Export in spreadsheet"; // XXX + var export2Button = h('button.btn.btn-primary', [ + h('i.fa.fa-download'), + Messages.form_exportSheet + ]); + $(export2Button).appendTo($controls); + $(export2Button).click(function () { + var arr = Exporter.results(content, answers, TYPES, true); + if (!arr) { return void UI.warn(Messages.error); } + console.error(arr); + }); + var summary = true; var form = content.form; From aaed6b7d770d3c8df70b39c835f996ef6cc5da9c Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 24 Sep 2021 16:31:26 +0200 Subject: [PATCH 14/17] Apply form results to new sheet --- www/common/common-ui-elements.js | 9 +++++++++ www/common/onlyoffice/inner.js | 10 ++++++++++ www/common/sframe-common-outer.js | 8 ++++++++ www/form/inner.js | 7 ++++++- www/form/main.js | 9 ++++++++- 5 files changed, 41 insertions(+), 2 deletions(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 08e0bcf07..4be00efec 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -2268,6 +2268,7 @@ define([ var type = metadataMgr.getMetadataLazy().type || privateData.app; var fromFileData = privateData.fromFileData; + var fromContent = privateData.fromContent; var $body = $('body'); var $creationContainer = $('
', { id: 'cp-creation-container' }).appendTo($body); @@ -2524,6 +2525,14 @@ define([ todo(res.data); }); } + else if (fromContent) { + allData = [{ + name: fromContent.title, + id: 0, + icon: h('span.cptools.cptools-poll'), + }]; + redraw(0); + } else { redraw(0); } diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 7bbfc7d0d..e1ee042ee 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -1440,11 +1440,16 @@ define([ // to be downloaded and decrypted before converting to xlsx var downloadImages = {}; + var firstOO = true; startOO = function (blob, file, force) { if (APP.ooconfig && !force) { return void console.error('already started'); } var url = URL.createObjectURL(blob); var lock = !APP.history && (APP.migrate); + var fromContent = metadataMgr.getPrivateData().fromContent; + if (!firstOO) { fromContent = undefined; } + firstOO = false; + // Starting from version 3, we can use the view mode again // defined but never used //var mode = (content && content.version > 2 && lock) ? "view" : "edit"; @@ -1606,6 +1611,11 @@ define([ } } + if (fromContent && !lock && Array.isArray(fromContent.content)) { + console.warn(fromContent); + makePatch(fromContent.content); + } + if (APP.isDownload) { var bin = getContent(); if (!supportsXLSX()) { diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 21344cd3f..bce02657b 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -300,6 +300,13 @@ define([ })); }; + if (sessionStorage.CP_formExportSheet && parsed.type === 'sheet') { + try { + Cryptpad.fromContent = JSON.parse(sessionStorage.CP_formExportSheet); + } catch (e) { console.error(e); } + delete sessionStorage.CP_formExportSheet; + } + // New pad options var options = parsed.getOptions(); if (options.newPadOpts) { @@ -639,6 +646,7 @@ define([ fromFileData: Cryptpad.fromFileData ? (isOO ? Cryptpad.fromFileData : { title: Cryptpad.fromFileData.title }) : undefined, + fromContent: Cryptpad.fromContent, burnAfterReading: burnAfterReading, storeInTeam: Cryptpad.initialTeam || (Cryptpad.initialPath ? -1 : undefined), supportsWasm: Utils.Util.supportsWasm() diff --git a/www/form/inner.js b/www/form/inner.js index c46ccb43a..0920bfa5f 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -2647,7 +2647,12 @@ define([ $(export2Button).click(function () { var arr = Exporter.results(content, answers, TYPES, true); if (!arr) { return void UI.warn(Messages.error); } - console.error(arr); + var sframeChan = framework._.sfCommon.getSframeChannel(); + var title = framework._.title.title || framework._.title.defaultTitle; + sframeChan.event('EV_EXPORT_SHEET', { + title: title, + content: arr + }); }); var summary = true; diff --git a/www/form/main.js b/www/form/main.js index 7204435d2..8993749fb 100644 --- a/www/form/main.js +++ b/www/form/main.js @@ -51,7 +51,14 @@ define([ Cryptpad.setPadAttribute('answersChannel', data.channel, function () {}); }); }); - + }); + sframeChan.on('EV_EXPORT_SHEET', function (data) { + if (!data || !Array.isArray(data.content)) { return; } + sessionStorage.CP_formExportSheet = JSON.stringify(data); + var href = Utils.Hash.hashToHref('', 'sheet'); + var a = window.open(href); + if (!a) { sframeChan.event('EV_POPUP_BLOCKED'); } + delete sessionStorage.CP_formExportSheet; }); var getAnonymousKeys = function (formSeed, channel) { var array = Nacl.util.decodeBase64(formSeed + channel); From f0925751045fab2b289836a32afd628f1f6a8704 Mon Sep 17 00:00:00 2001 From: David Benque Date: Mon, 27 Sep 2021 09:54:30 +0100 Subject: [PATCH 15/17] Adjust "export to spreadsheet" forms UI --- customize.dist/src/less2/include/forms.less | 3 --- www/form/inner.js | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/customize.dist/src/less2/include/forms.less b/customize.dist/src/less2/include/forms.less index 2eace9f29..30c2e9197 100644 --- a/customize.dist/src/less2/include/forms.less +++ b/customize.dist/src/less2/include/forms.less @@ -117,9 +117,6 @@ margin-right: 5px; } } - .cptools { - vertical-align: middle; - } color: @cp_buttons-fg; border: 1px solid @cp_buttons-fg; diff --git a/www/form/inner.js b/www/form/inner.js index 0920bfa5f..888a064e9 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -2638,9 +2638,9 @@ define([ }); // Export in "sheet" - Messages.form_exportSheet = "Export in spreadsheet"; // XXX + Messages.form_exportSheet = "Export to spreadsheet"; // XXX var export2Button = h('button.btn.btn-primary', [ - h('i.fa.fa-download'), + h('i.cptools.cptools-sheet'), Messages.form_exportSheet ]); $(export2Button).appendTo($controls); From 7ae5654b8394d87fa376285e5eea6078ceca0ac4 Mon Sep 17 00:00:00 2001 From: ansuz Date: Mon, 27 Sep 2021 15:24:53 +0530 Subject: [PATCH 16/17] guard against type errors in contextual chat while in no-drive mode --- www/common/outer/messenger.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/common/outer/messenger.js b/www/common/outer/messenger.js index 981d9f8de..85400adc0 100644 --- a/www/common/outer/messenger.js +++ b/www/common/outer/messenger.js @@ -617,11 +617,11 @@ define([ return void cb({error: 'NO_SUCH_CHANNEL'}); } - var proxy = ctx.store.proxy; + var proxy = ctx.store.proxy || {}; var msg = [Types.message, proxy.curvePublic, +new Date(), payload]; if (!channel.isFriendChat) { var name = proxy[Constants.displayNameKey] || - Messages.anonymous + '#' + proxy.uid.slice(0,5); + Messages.anonymous + '#' + (proxy.uid || ctx.store.noDriveUid).slice(0,5); msg.push(name); } var msgStr = JSON.stringify(msg); From 04e298dd461b99328334dc94258111266fa7eaed Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 28 Sep 2021 15:44:21 +0200 Subject: [PATCH 17/17] Fix forms results with conditional sections (#799) --- www/form/export.js | 6 +++--- www/form/inner.js | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/www/form/export.js b/www/form/export.js index 4afc4170a..8983fd06c 100644 --- a/www/form/export.js +++ b/www/form/export.js @@ -13,14 +13,14 @@ define([ value += '"' + vv + '"'; return value; }; - Export.results = function (content, answers, TYPES) { + Export.results = function (content, answers, TYPES, order) { if (!content || !content.form) { return; } var csv = ""; var form = content.form; var questions = [Messages.form_poll_time, Messages.share_formView]; - content.order.forEach(function (key) { + order.forEach(function (key) { var obj = form[key]; if (!obj) { return; } var type = obj.type; @@ -44,7 +44,7 @@ define([ var user = msg._userdata || {}; csv += escapeCSV(time); csv += ',' + escapeCSV(user.name || Messages.anonymous); - content.order.forEach(function (key) { + order.forEach(function (key) { var type = form[key].type; if (!TYPES[type]) { return; } // Ignore static types if (TYPES[type].exportCSV) { diff --git a/www/form/inner.js b/www/form/inner.js index cb300facd..55d92f094 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -2628,7 +2628,7 @@ define([ var $results = $(results).appendTo($container); $(exportButton).click(function () { - var csv = Exporter.results(content, answers, TYPES); + var csv = Exporter.results(content, answers, TYPES, getFullOrder(content)); if (!csv) { return void UI.warn(Messages.error); } var suggestion = APP.framework._.title.suggestTitle('cryptpad-document'); var title = Util.fixFileName(suggestion) + '.csv'; @@ -2644,7 +2644,8 @@ define([ $controls.hide().append(switchMode); var show = function (answers, header) { - var elements = content.order.map(function (uid) { + var order = getFullOrder(content); + var elements = order.map(function (uid) { var block = form[uid]; var type = block.type; var model = TYPES[type];