Compare commits

...

99 Commits

Author SHA1 Message Date
ansuz b1281fb4ab Merge branch 'soon' into staging 2021-07-28 15:19:49 +05:30
ansuz b3a7d5c42c factor out some duplicated code for handling 24 dates 2021-07-28 15:19:05 +05:30
ansuz f80aacc177 prevent incorrect removal of form submission buttons
...by guarding against overflow of a setTimeout delay
2021-07-28 15:17:25 +05:30
ansuz 5f32a38f3e Merge branch 'soon' into main 2021-07-28 03:45:09 +05:30
ansuz a613b64b77 use brand link color for links in the form app 2021-07-28 03:43:36 +05:30
ansuz 106dd007ac Merge branch 'staging' into soon 2021-07-28 03:19:18 +05:30
Weblate ef56a8f863 Translated using Weblate (Japanese)
Currently translated at 99.8% (1377 of 1379 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/
2021-07-27 17:47:04 +02:00
Weblate 9256c45a26 Translated using Weblate (German)
Currently translated at 100.0% (1379 of 1379 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/de/
2021-07-27 17:47:04 +02:00
Weblate 4fe5b11370 Translated using Weblate (French)
Currently translated at 100.0% (1379 of 1379 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/fr/
2021-07-27 17:47:04 +02:00
David Benqué dc74df0ac5 Minor edits to the changelog 2021-07-27 16:31:05 +01:00
ansuz 673ed629d6 update changelog for 4.9.0 2021-07-27 17:14:53 +05:30
ansuz 7916f36007 update version string to 4.9.0 2021-07-27 05:27:05 +05:30
ansuz 32027f09d6 refine link name placeholder suggestion and provide a more descriptive error message 2021-07-27 05:21:05 +05:30
ansuz 45b58d622d rewrite a switch statement as a concise lookup table 2021-07-27 05:19:35 +05:30
ansuz 921da962d0 narrow exceptions for use of localhost in checkup 2021-07-27 05:18:39 +05:30
ansuz 3eb2e77ed8 update changelog 2021-07-27 05:16:52 +05:30
ansuz 860f4cb44b Merge branch 'soon' into staging 2021-07-27 05:16:21 +05:30
Weblate 9258d21ef0 Translated using Weblate (English)
Currently translated at 100.0% (1379 of 1379 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/
2021-07-27 01:23:51 +02:00
Weblate ea6d5e8876 Translated using Weblate (Japanese)
Currently translated at 99.8% (1376 of 1378 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/
2021-07-27 01:23:51 +02:00
ansuz 95369ae87d Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging 2021-07-27 03:41:12 +05:30
ansuz 9c373377cf send feedback for UI related to the new link functionality 2021-07-27 03:40:48 +05:30
ansuz 854a635c5f remove hardcoded translations and defer non-blocking issues till the next release 2021-07-27 03:40:03 +05:30
David Benqué 04a616f87d Add margin to individual response list
- prevents response title to be mixed up with first question
2021-07-26 15:38:21 +01:00
ansuz a4b89fff84 Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging 2021-07-26 19:57:10 +05:30
David Benqué 4f5a041010 Style username in poll results table 2021-07-26 15:26:51 +01:00
ansuz 4e900b18cf use more specific 'export to CSV' translation in forms 2021-07-26 19:56:49 +05:30
ansuz 126a3fff46 remove hardcoded translations and rework link name placeholder behaviour 2021-07-26 19:56:11 +05:30
ansuz 2ca98425f2 Merge branch 'soon' into staging 2021-07-26 19:36:04 +05:30
Weblate c35ccfc6bb Translated using Weblate (English)
Currently translated at 100.0% (1378 of 1378 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/

Translated using Weblate (English)

Currently translated at 100.0% (1378 of 1378 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/
2021-07-26 16:05:20 +02:00
ansuz 09fe994443 Merge branch 'soon' into staging 2021-07-26 19:24:15 +05:30
Weblate 55b00409b3 Translated using Weblate (Japanese)
Currently translated at 100.0% (1376 of 1376 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/
2021-07-26 15:53:26 +02:00
Weblate fc64913392 Translated using Weblate (English)
Currently translated at 100.0% (1377 of 1377 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/
2021-07-26 15:53:25 +02:00
Weblate b0f7a9488c Translated using Weblate (English)
Currently translated at 100.0% (1376 of 1376 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/

Translated using Weblate (English)

Currently translated at 100.0% (1375 of 1375 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/

Translated using Weblate (English)

Currently translated at 100.0% (1374 of 1374 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/

Translated using Weblate (English)

Currently translated at 100.0% (1373 of 1373 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/

Translated using Weblate (English)

Currently translated at 100.0% (1372 of 1372 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/

Translated using Weblate (English)

Currently translated at 100.0% (1371 of 1371 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/

Translated using Weblate (English)

Currently translated at 100.0% (1370 of 1370 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/

Translated using Weblate (English)

Currently translated at 100.0% (1369 of 1369 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/
2021-07-26 15:52:03 +02:00
Weblate 0534a69f3d Translated using Weblate (Japanese)
Currently translated at 99.9% (1375 of 1376 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (1373 of 1373 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/

Translated using Weblate (Japanese)

Currently translated at 99.9% (1371 of 1372 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (1370 of 1370 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/
2021-07-26 15:52:02 +02:00
David Benqué 24401f39e1 Merge remote-tracking branch 'origin/staging' into staging 2021-07-26 14:29:02 +01:00
David Benqué e3150f1284 Add margin above anonymous name field 2021-07-26 14:28:55 +01:00
ansuz 4862e9b0cc use two translation keys for 'Link' UI in different contexts 2021-07-26 18:14:01 +05:30
ansuz 987fb696ed downgrade urgency of unhandled form notes 2021-07-26 18:12:31 +05:30
ansuz 812d5f7146 disable form response message UI until it's been reviewed more 2021-07-26 18:11:45 +05:30
ansuz 8a1aef9792 Merge branch 'soon' into staging 2021-07-26 17:07:59 +05:30
ansuz 403d922ddd replace two XXX notes with comments 2021-07-26 16:30:49 +05:30
ansuz f178d4bebc update pending changelog 2021-07-26 15:51:15 +05:30
ansuz 52d5bb5ae8 add notes to gather feedback about the new link feature 2021-07-26 15:28:20 +05:30
ansuz ec928334d8 don't try to pin channels with invalid lengths 2021-07-26 15:26:23 +05:30
ansuz d21e79733e send feedback when self-destructing pads explode 2021-07-26 15:24:08 +05:30
ansuz 513f1531e3 remove some dead code 2021-07-26 15:03:02 +05:30
ansuz e5558b516c guard against a typeError when drive-less users try to send a pad-burned notification 2021-07-26 15:02:48 +05:30
ansuz 7bc6ed17b9 update max choices input in forms
...when the maximum exceeds the number of choices
2021-07-26 14:57:28 +05:30
ansuz 99c11f032e tally form votes with an increment function 2021-07-26 14:53:04 +05:30
ansuz 9ca3682df9 fix an accidentally flipped boolean 2021-07-26 14:10:32 +05:30
ansuz 3c6c517506 Merge branch 'forms' into staging 2021-07-26 13:22:51 +05:30
ansuz 8200f579a8 Merge branch 'link' into staging 2021-07-26 13:07:38 +05:30
ansuz 6578b66ba6 convert a warning to an error 2021-07-26 13:07:23 +05:30
ansuz 2019e1d70a implement minor fixes and add comments following code review 2021-07-26 13:05:47 +05:30
Weblate 79541dd914 Translated using Weblate (Japanese)
Currently translated at 100.0% (1368 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (1368 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (1368 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (1368 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (1368 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (1368 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/
2021-07-24 13:30:04 +02:00
Weblate af8ef252e6 Translated using Weblate (Chinese (Simplified))
Currently translated at 17.8% (244 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/zh_Hans/
2021-07-24 13:30:04 +02:00
Weblate 9b192a8e4c Translated using Weblate (Lithuanian)
Currently translated at 14.9% (204 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/lt/
2021-07-24 13:30:03 +02:00
yflory f5fc4f28bf Improve forms CSV export with polls 2021-07-23 17:51:56 +02:00
yflory a93a9f14d3 Fix initial title with forms templates 2021-07-23 17:51:42 +02:00
yflory 212b3d4884 Form fixes and improvements 2021-07-23 14:47:30 +02:00
yflory 6c720ce9d1 Fix type error 2021-07-23 10:18:42 +02:00
yflory 6faaec5042 lint compliance 2021-07-22 12:06:48 +02:00
yflory 667bef2a84 Fix links in shared folders 2021-07-21 17:19:35 +02:00
yflory 511ec211c1 Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging 2021-07-21 11:42:57 +02:00
yflory 0a5614b79f Fix team invitation link #774 2021-07-21 11:37:44 +02:00
ansuz d44ae0b0b0 Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging 2021-07-20 17:44:25 +05:30
yflory 4e6ff7716f Merge branch 'staging' into link 2021-07-20 10:52:07 +02:00
yflory d530a51f99 Fix premium ticket category in admin panel 2021-07-20 10:51:12 +02:00
yflory 1a88baf9c3 lint compliance 2021-07-20 10:48:25 +02:00
yflory e38206ffb3 Fix premium tickets 2021-07-20 10:46:40 +02:00
yflory 775b741049 Merge branch 'staging' into link 2021-07-20 10:41:24 +02:00
yflory 0fc2269a3a Create links in the drive 2021-07-20 10:40:40 +02:00
ansuz 621941b933 comments about possible form improvements 2021-07-19 19:49:20 +05:30
ansuz a4092e888b remove unused images 2021-07-19 19:14:47 +05:30
ansuz 99323f0560 Merge branch 'soon' into staging 2021-07-15 16:13:31 +05:30
Weblate 1d9adbb096 Translated using Weblate (Japanese)
Currently translated at 100.0% (1368 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (1368 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ja/
2021-07-15 12:41:50 +02:00
Weblate 36eebd817d Translated using Weblate (Lithuanian)
Currently translated at 13.3% (182 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/lt/
2021-07-15 12:41:50 +02:00
yflory d94f327756 Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging 2021-07-12 15:37:07 +02:00
yflory 0929b5db47 Form improvements 2021-07-12 15:36:55 +02:00
ansuz c774a5d06e time out if checkup test #7 doesn't call back in 30s 2021-07-12 13:24:32 +05:30
Weblate 1d8811c42b Translated using Weblate (Catalan)
Currently translated at 39.4% (540 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ca/
2021-07-12 06:18:18 +02:00
Weblate 1faaff1665 Translated using Weblate (Lithuanian)
Currently translated at 9.3% (128 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/lt/

Translated using Weblate (Lithuanian)

Currently translated at 7.9% (109 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/lt/
2021-07-12 06:18:18 +02:00
ansuz 32e79d323d add support for tabs in ckeditor
and leave a note about the challenges of accessibility here
2021-07-09 18:53:27 +05:30
ansuz 55c974d025 Merge branch 'soon' into staging 2021-07-09 18:13:32 +05:30
ansuz ae77f1c6b9 Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging 2021-07-09 18:13:30 +05:30
ansuz 4e9a9681f4 Merge branch 'main' into soon 2021-07-09 18:13:18 +05:30
ansuz 3f1b6ba74d some minor fixes for anon drives
* don't show the collapse tree button in the toolbar
* display the bread crumb when viewing shared folders
2021-07-09 16:44:13 +05:30
ansuz 90b6787fa8 disable cache usage for form results 2021-07-09 16:43:48 +05:30
ansuz 5b3dcde28c disable cache usage for form results 2021-07-09 16:43:17 +05:30
yflory 4117274e59 Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging 2021-07-09 12:30:04 +02:00
yflory 1b0a0fe14f Improve reset button in forms 2021-07-09 11:56:53 +02:00
yflory 1b081c52df lint compliance 2021-07-09 11:46:32 +02:00
yflory ed28b5ec7b Randomize 'ordered list' initial state in forms 2021-07-09 11:45:48 +02:00
yflory f46a820ad8 Don't sort 'sorted lists' in forms by default 2021-07-09 11:41:12 +02:00
ansuz b6755f4d58 Merge branch 'soon' into staging 2021-07-09 15:08:53 +05:30
Weblate 2e5632988e Translated using Weblate (Catalan)
Currently translated at 39.1% (536 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ca/
2021-07-09 11:34:47 +02:00
Weblate d6e97b16c1 Translated using Weblate (Hindi)
Currently translated at 0.3% (5 of 1368 strings)

Translation: CryptPad/App
Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/hi/
2021-07-09 11:34:47 +02:00
ansuz eff65f6e71 add file for Lithuanian translation 2021-07-09 15:04:28 +05:30
ansuz 6df790dbba some minor fixes for anon drives
* don't show the collapse tree button in the toolbar
* display the bread crumb when viewing shared folders
2021-07-08 17:55:31 +05:30
51 changed files with 1264 additions and 218 deletions

View File

@ -1,3 +1,46 @@
# 4.9.0
## Goals and announcements
We allocated most of this release cycle towards a schedule of one-on-one user interviews and some broad usage studies leveraging our new Form app. The remainder of our time was spent on some minor improvements. We'll continue at a slightly slower pace of implementation for the coming weeks while we complete our scheduled interviews and take some much-needed vacations.
## Update notes
It appears our promotion of the checkup page through our recent release notes and the inclusion of a link to it from the instance admin have been moderately successful. We've observed that more instance admins are noticing and fixing some common configuration issues.
This release features some minor changes to one instance configuration test which incorrectly provided an exemption for the use of `http://localhost:3000` as an `httpUnsafeOrigin` value. This exemption was provided because this value is valid for local development. However, it suppressed errors when this configuration was used for production instances where it could cause a variety of problems. As usual, we recommend checking your instance's admin page after updating to confirm that you are passing the latest tests. Information about the checkup page is included in [our documentation](https://docs.cryptpad.fr/en/admin_guide/admin_panel.html#network).
To update from 4.8.0 to 4.9.0:
1. Stop your server
2. Get the latest code with git
3. Install the latest dependencies with `bower update` and `npm i`
4. Restart your server
5. Confirm that your instance is passing all the tests included on the `/checkup/` page
## Features
* We've added the ability to store URLs in user and team drives as requested in a private support ticket and [this issue](https://github.com/xwiki-labs/cryptpad/issues/732). Links can be shared directly with contacts. Unlike pads, links are not collaborative objects, so updating a link's name will not update the entry in another user's drive if you've already shared it with them. Links are integrated into our apps' _insert_ menu to facilitate quick insertion of links you've stored into your documents. We're interested in measuring how this functionality is used in practice so we can decide whether it's worth spending more time on it. We have added some telemetry to measure (in aggregate) how often its components are used. We anonymize IP addresses in the logs for CryptPad.fr, but as always, you can disable telemetry via your settings panel.
* Our rich text editor now supports indentation with the tab key, as per [issue #634](https://github.com/xwiki-labs/cryptpad/issues/634).
* Forms received another round of improvements to styles, workflows, and some basic survey functionality to yield more accurate results.
* Ordered lists are now shuffled for each survey participant so that their initial order has less effect on the final results.
* CSV export now uses one column for each option in polls, making them easier to read.
* Unregistered users can now add a name to their response.
* Form results are displayed automatically (when available) to those who have answered.
* Authors and auditors can now click on usernames in polls to jump directly to other answers from the same user.
* Users with very large drives might notice that their account loads slightly faster now, due to some minor optimizations in an integrity check that the client performs when loading accounts.
## Bugs
* We've added a guard against a type error that could be triggered when loading teams under certain rare conditions.
* Unregistered users' drives now show the "bread-crumb" UI for navigating between folders when viewing a shared folder in read-only mode. We've also suppressed the "Files" button for displaying the tree view which was non-functional for such users.
* A change in the format of support tickets caused tickets recently created by premium users to not be recognized as such. We've fixed the categorization in the admin panel's support ticket view.
* We've fixed a number of minor issues with forms:
* The maximum number of selectable choices for checkbox questions can no longer exceed the number of available choices.
* We guard against a type error that could occur when parsing dates.
* Forms imported from templates now have their initial title corrected.
* We've disabled the use of our indexedDB caching system for form results, since it was quietly dropping older responses when more than 100 responses had been submitted. We plan to re-enable caching for results once we've updated the eviction metric to better handle the response format.
# 4.8.0
## Goals

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 83 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360.4 94.7"><defs><style>.cls-1{fill:#4591c4}.cls-2{fill:#999}</style></defs><title>CryptPad_logo_color</title><g id="Layer_2" data-name="Layer 2"><g id="svg2"><g id="g4845"><path id="path4811" class="cls-1" d="M99.5 63.6a24.8 24.8 0 0 1-5.9-.6 8.5 8.5 0 0 1-3.8-1.9 7.1 7.1 0 0 1-2-3.4 19.4 19.4 0 0 1-.6-5.2v-10a19.4 19.4 0 0 1 .6-5.1 7.1 7.1 0 0 1 2-3.4 8.5 8.5 0 0 1 3.8-2 24.8 24.8 0 0 1 5.9-.6h22.3v6.2h-22a11.8 11.8 0 0 0-2.7.3 3.5 3.5 0 0 0-1.7.9 3.3 3.3 0 0 0-.9 1.6 11.1 11.1 0 0 0-.2 2.5v9.4a11.1 11.1 0 0 0 .2 2.5 3.3 3.3 0 0 0 .9 1.6 3.3 3.3 0 0 0 1.7.8l2.7.2h22v6.1z"/><path id="path4813" class="cls-1" d="M126.5 63.6V48.8a16 16 0 0 1 .7-4.9 7.5 7.5 0 0 1 2.1-3.3 8.9 8.9 0 0 1 3.7-1.9 21.4 21.4 0 0 1 5.5-.6h4.6v5.7h-4.4l-2.5.2a3.3 3.3 0 0 0-1.6.8 3.2 3.2 0 0 0-.8 1.6 10.1 10.1 0 0 0-.3 2.5v14.7z"/><path id="path4815" class="cls-1" d="M154.1 51.4a3.8 3.8 0 0 0 .9 3 4.6 4.6 0 0 0 3.1.8h15.7V38h6.8v25.2q0 4.3-2.1 6.2t-6.9 1.9h-10.2v-5.8h9.6a3.3 3.3 0 0 0 2.1-.6 2.7 2.7 0 0 0 .7-2.2v-2h-16.1a19 19 0 0 1-4.9-.5 7.8 7.8 0 0 1-3.3-1.7 6.5 6.5 0 0 1-1.8-2.8 12.7 12.7 0 0 1-.6-4V38h6.9z"/><path id="path4817" class="cls-1" d="M207.5 38a25.1 25.1 0 0 1 5.9.6 8.5 8.5 0 0 1 3.8 1.9 7.1 7.1 0 0 1 2 3.4 19.7 19.7 0 0 1 .6 5.2v3.4a19.4 19.4 0 0 1-.6 5.2 7.1 7.1 0 0 1-2 3.4 8.5 8.5 0 0 1-3.8 1.9 25.1 25.1 0 0 1-5.9.6h-14.3v7.6h-7V49.1a19.7 19.7 0 0 1 .6-5.2 7.1 7.1 0 0 1 2-3.4 8.6 8.6 0 0 1 3.8-1.9 25.1 25.1 0 0 1 5.9-.6zm5.3 11.3a11.7 11.7 0 0 0-.3-2.7 2.9 2.9 0 0 0-1-1.6 4 4 0 0 0-1.9-.8l-3-.2h-7.8l-2.7.2a3.5 3.5 0 0 0-1.7.8 3.2 3.2 0 0 0-.8 1.6 11.7 11.7 0 0 0-.2 2.6v8.4h13.4l3-.2a3.8 3.8 0 0 0 1.9-.7 2.9 2.9 0 0 0 1-1.6 11.9 11.9 0 0 0 .3-2.8z"/><path id="path4819" class="cls-1" d="M226.5 63.6V43.8H223V38h3.6v-7.2h7.2V38h8.1v5.7h-8.1v19.9z"/><path id="path4821" class="cls-2" d="M252.4 54.4v9.2h-7.2V31.4H271a25.7 25.7 0 0 1 5.8.5 8.4 8.4 0 0 1 3.7 1.8 6.8 6.8 0 0 1 2 3.2 17.1 17.1 0 0 1 .6 4.8v2.8a16.9 16.9 0 0 1-.6 4.8 6 6 0 0 1-2 3 8.3 8.3 0 0 1-3.7 1.6 31.6 31.6 0 0 1-5.9.4zm23.5-12.3q0-2.6-1.1-3.5t-4-.9h-18.4v11h18.5a6.5 6.5 0 0 0 3.9-.9q1.1-.9 1.1-3.4z"/><path id="path4823" class="cls-2" d="M296.2 63.6a18.4 18.4 0 0 1-4.6-.5 7.4 7.4 0 0 1-2.9-1.3 4.6 4.6 0 0 1-1.5-2.1 8.7 8.7 0 0 1-.4-2.8v-2.4a9.3 9.3 0 0 1 .4-2.9 4.7 4.7 0 0 1 1.4-2.1 6.5 6.5 0 0 1 2.7-1.3 17.7 17.7 0 0 1 4.4-.4h18.9v-.6q0-2.5-1-3.3a5.3 5.3 0 0 0-3.4-.8h-7V38h7a20.7 20.7 0 0 1 5.2.6 8.9 8.9 0 0 1 3.5 1.7 6.7 6.7 0 0 1 2 2.9 12.5 12.5 0 0 1 .6 4.2v6.2a17.2 17.2 0 0 1-.5 4.7 6.3 6.3 0 0 1-1.9 3.1 7.9 7.9 0 0 1-3.6 1.7 26.8 26.8 0 0 1-5.6.5zM314.7 52h-18.2a3.1 3.1 0 0 0-1.9.5 2.5 2.5 0 0 0-.7 2.1v1.7a2.1 2.1 0 0 0 .8 1.9 3.7 3.7 0 0 0 2.1.5H310l2.1-.2a3.2 3.2 0 0 0 1.5-.7 3 3 0 0 0 .9-1.4 7.8 7.8 0 0 0 .3-2.3z"/><path id="path4825" class="cls-2" d="M339.1 63.6a25.4 25.4 0 0 1-6-.6 8.6 8.6 0 0 1-3.8-1.9 7.1 7.1 0 0 1-2-3.4 19.4 19.4 0 0 1-.6-5.2v-3.4a19.7 19.7 0 0 1 .6-5.2 7.1 7.1 0 0 1 2-3.4 8.6 8.6 0 0 1 3.8-1.9 25.4 25.4 0 0 1 6-.6h14.2v-8.2h7v22.8a19.4 19.4 0 0 1-.6 5.2 7.1 7.1 0 0 1-2 3.4A8.5 8.5 0 0 1 354 63a25.1 25.1 0 0 1-5.9.6zm-5.3-11.2a11.7 11.7 0 0 0 .3 2.7 2.9 2.9 0 0 0 1 1.6 4 4 0 0 0 1.9.8l3.1.2h7.8l2.7-.2a3.3 3.3 0 0 0 1.7-.8 3.2 3.2 0 0 0 .9-1.6 11.9 11.9 0 0 0 .2-2.6v-8.4H340l-3 .2a4 4 0 0 0-1.9.8 2.9 2.9 0 0 0-1 1.6 11.7 11.7 0 0 0-.3 2.7z"/><path id="path4827" class="cls-1" d="M39.2 0L9.9 5.4A6.3 6.3 0 1 0 3.2 16v42.2c0 4 1.8 8.3 5.3 12.7A65.5 65.5 0 0 0 21.6 83a128.2 128.2 0 0 0 17.6 10.5A128.1 128.1 0 0 0 56.7 83a65.4 65.4 0 0 0 13.1-12.1c3.5-4.5 5.3-8.8 5.3-12.7V16A6.3 6.3 0 0 0 72 4.2a6.2 6.2 0 0 0-3.6 1.2zm-.1 6.2l26.7 4.9a5.9 5.9 0 0 0 .2 1.1L50.3 22.5a15.3 15.3 0 0 0-22.6.1l-15.5-10a6.3 6.3 0 0 0 .3-1.4zm28.8 9a6.5 6.5 0 0 0 1.8 1.1v41a10.4 10.4 0 0 1-.1 1.7 21.5 21.5 0 0 1-4.1 7.8 56.1 56.1 0 0 1-11.3 10.4 110.6 110.6 0 0 1-15 9 110.8 110.8 0 0 1-15-9A55.8 55.8 0 0 1 13 66.8a19.8 19.8 0 0 1-4.4-9.3V16.4a6.3 6.3 0 0 0 1.7-1l19.8 12.7a10.1 10.1 0 0 1 9-5.4 10 10 0 0 1 9 5.4z"/><g id="g4829"><path id="path4831" class="cls-2" d="M23 54.8a4.6 4.6 0 1 0 0 9.3 4.6 4.6 0 0 0 0-9.3z"/><path id="path4833" class="cls-2" d="M24.3 28.5a14.9 14.9 0 0 0 4.2 15.4l-7.3 14.8a2.8 2.8 0 0 0 2.3 3.8h11v-5.2h-6.8l6.4-12.8a2.7 2.7 0 0 0-.8-3.3 9.7 9.7 0 0 1-4.3-9.6z"/></g><g id="g4835"><path id="path4837" class="cls-2" d="M55.3 54.8a4.6 4.6 0 1 0 0 9.3 4.6 4.6 0 0 0 0-9.3z"/><path id="path4839" class="cls-2" d="M53.8 28.6l-4.7 3.1a10.2 10.2 0 0 1 .1 1.2 10 10 0 0 1-4.3 8.3 2.7 2.7 0 0 0-.8 3.3l6.3 12.8h-6.8v5.2h11a2.8 2.8 0 0 0 2.3-3.8l-7.3-14.8a15.2 15.2 0 0 0 4.8-11 15.3 15.3 0 0 0-.6-4.3z"/></g><path id="path4841" class="cls-1" d="M43.2 33.3a4.2 4.2 0 1 1-4.2-4.2 4.2 4.2 0 0 1 4.2 4.2z"/><path id="path4843" class="cls-1" d="M45.3 88.4a6.3 6.3 0 1 1-6.3-6.3 6.3 6.3 0 0 1 6.3 6.3z"/></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 393.94 476.2"><defs><style>.cls-1{opacity:0.04;}.cls-2{fill:#999;}.cls-3{fill:#4591c4;}</style></defs><title>CryptPadlogo</title><g id="Layer_2" data-name="Layer 2"><g id="svg2"><g id="g4764" class="cls-1"><path class="cls-2" d="M139.36,288.16l32.07-64.43a13.59,13.59,0,0,0-4.23-16.62,48.65,48.65,0,0,1-21.28-48.25l-23.47-15.31a75.74,75.74,0,0,0-3.36,21.87c0,22,9.52,41.45,24.35,55.54l-27.24,54.8c-.11,0-.2,0-.31,0a23.27,23.27,0,1,0,0,46.53,23,23,0,0,0,17.31-7.86h40.27V288.16Z"/><path class="cls-2" d="M278.28,275.73c-.57,0-1.11.13-1.68.17l-27.33-55.09c14.75-14.07,24.2-33.47,24.2-55.39a77.13,77.13,0,0,0-3.06-21.72l-23.62,15.45a51.69,51.69,0,0,1,.44,6.27A50.21,50.21,0,0,1,225.65,207a13.58,13.58,0,0,0-4.22,16.62l31.77,64.58h-34V314.4h41.63a23.23,23.23,0,1,0,17.41-38.67Z"/><polygon class="cls-2" points="270.41 143.7 270.41 143.7 270.41 143.7 270.41 143.7"/><circle class="cls-3" cx="196.06" cy="167.4" r="21.21"/><path class="cls-3" d="M362.25,21.36a31.14,31.14,0,0,0-18.1,5.8L197,0,50,27.16a31.62,31.62,0,1,0-33.68,53.4v212c0,19.95,8.93,41.51,26.62,64.08,15.66,20,37.82,40.46,65.89,60.83a603,603,0,0,0,57,36.21,31.54,31.54,0,0,0,60,1.25,606,606,0,0,0,59.26-37.46c28.09-20.37,50.23-40.86,65.9-60.83,17.7-22.6,26.61-44.13,26.61-64.08V80.38a31.46,31.46,0,0,0-15.39-59ZM62.82,55.94,196.61,31.32l134.33,24.8a29.58,29.58,0,0,0,.9,5.61L253.09,113a76.78,76.78,0,0,0-113.69.36L61.55,62.82A31.8,31.8,0,0,0,62.82,55.94ZM350.49,288.21a51.41,51.41,0,0,1-.73,8.51c-3.16,12.6-10.11,25.8-20.82,39.47-13.41,17.09-32.43,34.52-56.48,51.95a532.75,532.75,0,0,1-54.19,34.09,31.5,31.5,0,0,0-43.73-.62,534,534,0,0,1-53.06-33.47c-24-17.43-42.9-34.86-56.31-51.95-12.77-16.31-20.25-31.94-22.26-46.71,0-.41,0-.86,0-1.27V82.37a31.51,31.51,0,0,0,8.69-5.25l88.88,57.75.37-.36,10.5,6.88a51,51,0,0,1,45.07-27,50.37,50.37,0,0,1,45.08,27.15l22.09-14.3L341.44,76.4A32.55,32.55,0,0,0,350.49,82Z"/></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

View File

@ -105,7 +105,7 @@ define([
var imprintUrl = AppConfig.imprint && (typeof(AppConfig.imprint) === "boolean" ?
'/imprint.html' : AppConfig.imprint);
Pages.versionString = "v4.8.0";
Pages.versionString = "v4.9.0";
// used for the about menu

View File

@ -123,7 +123,7 @@ module.exports.create = function (config) {
maxWorkers: config.maxWorkers,
disableIntegratedTasks: config.disableIntegratedTasks || false,
disableIntegratedEviction: typeof(config.disableIntegratedEviction) === 'undefined'? true: config.disableIntegratedEviction, // XXX false,
disableIntegratedEviction: typeof(config.disableIntegratedEviction) === 'undefined'? true: config.disableIntegratedEviction, // XXX 4.10.0 false,
lastEviction: +new Date(),
evictionReport: {},
commandTimers: {},

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "cryptpad",
"version": "4.8.0",
"version": "4.9.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,7 +1,7 @@
{
"name": "cryptpad",
"description": "realtime collaborative visual editor with zero knowlege server",
"version": "4.8.0",
"version": "4.9.0",
"license": "AGPL-3.0+",
"repository": {
"type": "git",

View File

@ -833,7 +833,8 @@ define([
var premium = t.some(function (msg) {
var _ed = Util.find(msg, ['content', 'msg', 'content', 'sender', 'edPublic']);
if (ed !== _ed) { return; }
return Util.find(msg, ['content', 'msg', 'content', 'sender', 'plan']);
return Util.find(msg, ['content', 'msg', 'content', 'sender', 'plan']) ||
Util.find(msg, ['content', 'msg', 'content', 'sender', 'quota', 'plan']);
});
var lastMsg = t[t.length - 1];
var lastMsgEd = Util.find(lastMsg, ['content', 'msg', 'content', 'sender', 'edPublic']);
@ -1471,11 +1472,8 @@ define([
var end = h('input');
var $start = $(start);
var $end = $(end);
var is24h = false;
var is24h = UIElements.is24h();
var dateFormat = "Y-m-d H:i";
try {
is24h = !new Intl.DateTimeFormat(navigator.language, { hour: 'numeric' }).format(0).match(/AM/);
} catch (e) {}
if (!is24h) { dateFormat = "Y-m-d h:i K"; }
var endPickr = Flatpickr(end, {

View File

@ -255,6 +255,11 @@ define([
]));
}));
// time out after 30 seconds
setTimeout(function () {
cb('TIMEOUT');
}, 30000);
var bytes = new Uint8Array(Login.requiredBytes);
var opt = Login.allocateBytes(bytes);
@ -705,17 +710,19 @@ define([
var isOnion = function (host) {
return /\.onion$/.test(host);
};
var isLocalhost = function (host) {
return /^http:\/\/localhost/.test(host);
};
assert(function (cb, msg) {
// provide an exception for development instances
if (/http:\/\/localhost/.test(trimmedUnsafe)) { return void cb(true); }
if (isLocalhost(trimmedUnsafe) && isLocalhost(window.location.href)) { return void cb(true); }
// if both the main and sandbox domains are onion addresses
// then the HTTPS requirement is unnecessary
if (isOnion(trimmedUnsafe) && isOnion(trimmedSafe)) { return void cb(true); }
// otherwise expect that both inner and outer domains use HTTPS
setWarningClass(msg);
msg.appendChild(h('span', [
"Both ",
code('httpUnsafeOrigin'),
@ -727,8 +734,6 @@ define([
'. ',
RESTART_WARNING(),
]));
console.error("HTTPS?", trimmedUnsafe, trimmedSafe);
cb(isHTTPS(trimmedUnsafe) && isHTTPS(trimmedSafe));
});

View File

@ -368,7 +368,7 @@ define([
var mkFilePicker = function (framework, editor, evModeChange) {
evModeChange.reg(function (mode) {
if (MEDIA_TAG_MODES.indexOf(mode) !== -1) {
// Embedding is endabled
// Embedding is enabled
framework.setMediaTagEmbedder(function (mt) {
editor.focus();
editor.replaceSelection($(mt)[0].outerHTML);

View File

@ -119,6 +119,7 @@ define(function() {
file: 'cptools-file',
fileupload: 'cptools-file-upload',
folderupload: 'cptools-folder-upload',
link: 'fa-link',
pad: 'cptools-richtext',
code: 'cptools-code',
slide: 'cptools-slide',

View File

@ -1050,6 +1050,7 @@ define([
var font = icon.indexOf('cptools') === 0 ? 'cptools' : 'fa';
if (type === 'fileupload') { type = 'file'; }
if (type === 'folderupload') { type = 'file'; }
if (type === 'link') { type = 'drive'; }
var appClass = ' cp-icon cp-icon-color-'+type;
$icon = $('<span>', {'class': font + ' ' + icon + appClass});
}
@ -1061,6 +1062,7 @@ define([
if (!data) { return $icon; }
var href = data.href || data.roHref;
var type = data.type;
if (data.static) { type = 'link'; }
if (!href && !type) { return $icon; }
if (!type) { type = Hash.parsePadUrl(href).type; }

View File

@ -1032,10 +1032,19 @@ define([
icon: 'fa-picture-o',
action: function () {
var _cfg = {
types: ['file'],
types: ['file', 'link'],
where: ['root']
};
common.openFilePicker(_cfg, function (data) {
// Embed links
if (data.static) {
var a = h('a', {
href: data.href
}, data.name);
cfg.embed(a, data);
return;
}
// Embed files
if (data.type !== 'file') {
console.log("Unexpected data type picked " + data.type);
return;
@ -3021,6 +3030,75 @@ define([
UI.proposal(content, todo);
};
UIElements.displayOpenLinkModal = function (common, data, dismiss) {
var name = Util.fixHTML(data.title);
var url = data.href;
var user = data.name;
//Messages.link_open = "Open URL";
// openLinkInNewTab ("Open Link in New Tab")
// fc_open ("Open")
// share_linkOpen ("Preview")
// resources_openInNewTab ("Open it in a new tab")
Messages.link_open = Messages.fc_open; // XXX 4.10.0
//Messages.link_store = "Store link in drive";
// toolbar_storeInDrive ? ("Store in CryptDrive")
// autostore_store ? ("Store")
Messages.link_store = Messages.toolbar_storeInDrive; // XXX 4.10.0
var content = h('div', [
UI.setHTML(h('p'), Messages._getKey('notification_openLink', [name, user])),
h('pre', url),
UIElements.getVerifiedFriend(common, data.curve, user)
]);
var clicked = false;
var modal;
var buttons = [{
name: Messages.friendRequest_later,
onClick: function () {
if (clicked) { return true; }
clicked = true;
Feedback.send('LINK_RECEIVED_LATER');
},
keys: [27]
}, {
className: 'primary',
name: Messages.link_open,
onClick: function () {
if (clicked) { return true; }
clicked = true;
common.openUnsafeURL(url);
Feedback.send("LINK_RECEIVED_OPEN");
},
keys: [13]
}, {
className: 'primary',
name: Messages.link_store,
onClick: function () {
if (clicked) { return; }
clicked = true;
common.getSframeChannel().query("Q_DRIVE_USEROBJECT", {
cmd: "addLink",
data: {
name: name,
href: url,
path: ['root']
}
}, function () {
modal.closeModal();
dismiss();
Feedback.send("LINK_RECEIVED_STORE");
});
return true;
},
keys: [[13, 'ctrl']]
}];
var _modal = UI.dialog.customModal(content, {buttons: buttons});
modal = UI.openCustomModal(_modal);
return modal;
};
UIElements.displayAddOwnerModal = function (common, data) {
var priv = common.getMetadataMgr().getPrivateData();
var sframeChan = common.getSframeChannel();
@ -3618,6 +3696,13 @@ define([
return (pos.bottom < size) && (pos.y > 0);
};
UIElements.is24h = function () {
try {
return !new Intl.DateTimeFormat(navigator.language, { hour: 'numeric' }).format(0).match(/AM/);
} catch (e) {}
return false;
};
UIElements.openSnapshotsModal = function (common, load, make, remove) {
var modal;
var readOnly = common.getMetadataMgr().getPrivateData().readOnly;

View File

@ -9,6 +9,15 @@
return Array.prototype.slice.call(A, start, end);
};
Util.shuffleArray = function (a) {
for (var i = a.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
};
Util.bake = function (f, args) {
if (typeof(args) === 'undefined') { args = []; }
if (!Array.isArray(args)) { args = [args]; }
@ -152,6 +161,10 @@
};
};
Util.inc = function (map, key, val) {
map[key] = (map[key] || 0) + (typeof(val) === 'number'? val: 1);
};
Util.find = function (map, path) {
var l = path.length;
for (var i = 0; i < l; i++) {

View File

@ -443,6 +443,11 @@ define([
'data-icon': AppConfig.applicationsIcon.poll,
'data-type': 'poll'
}, Messages.button_newpoll)),
h('li', h('a.cp-app-drive-context-newdoc.dropdown-item.cp-app-drive-context-editable', {
'tabindex': '-1',
'data-icon': AppConfig.applicationsIcon.link,
'data-type': 'link'
}, Messages.fm_link_new)),
]),
]),
$separator.clone()[0],
@ -1106,11 +1111,24 @@ define([
common.getMediaTagPreview(mts, idx);
};
var refresh = APP.refresh = function () {
APP.displayDirectory(currentPath);
};
// `app`: true (force open wiht the app), false (force open in preview),
// falsy (open in preview if default is not using the app)
var defaultInApp = ['application/pdf'];
var openFile = function (el, isRo, app) {
var data = manager.getFileData(el);
if (data.static) {
if (data.href) {
common.openUnsafeURL(data.href);
manager.updateStaticAccess(el, refresh);
}
return;
}
if (!data || (!data.href && !data.roHref)) {
return void logError("Missing data for the file", el, data);
}
@ -1147,10 +1165,6 @@ define([
common.openURL(Hash.getNewPadURL(href, obj));
};
var refresh = APP.refresh = function () {
APP.displayDirectory(currentPath);
};
var pickFolderColor = function ($element, currentColor, cb) {
var colors = ["", "#f23c38", "#ff0073", "#da0eba", "#9d00ac", "#6c19b3", "#4a42b1", "#3d8af0", "#30a0f1", "#1fb9d1", "#009686", "#45b354", "#84c750", "#c6e144", "#faf147", "#fbc423", "#fc9819", "#fd5227", "#775549", "#9c9c9c", "#607a89"];
@ -1263,6 +1277,9 @@ define([
if ($element.is('.cp-border-color-sheet')) {
hide.push('download');
}
if ($element.is('.cp-app-drive-static')) {
hide.push('access', 'hashtag', 'properties', 'download');
}
if ($element.is('.cp-app-drive-element-file')) {
// No folder in files
hide.push('color');
@ -1899,6 +1916,31 @@ define([
// In list mode, display metadata from the filesData object
var addStaticData = function (element, $element, data) {
$element.addClass('cp-border-color-drive');
var name = data.name;
var $name = $('<span>', {'class': 'cp-app-drive-element-name'}).text(name);
$element.append($name);
if (getViewMode() === 'grid') {
//console.error(name, Util.fixHTML(name));
// this is only safe because our build of tippy sets titles as
// 'textContent' instead of innerHTML, otherwise
// we would need to use Util.fixHTML
$element.attr('title', name);
}
var type = Messages.fm_link_type;
var $type = $('<span>', {
'class': 'cp-app-drive-element-type cp-app-drive-element-list'
}).text(type);
var $adate = $('<span>', {
'class': 'cp-app-drive-element-atime cp-app-drive-element-list'
}).text(getDate(data.atime));
var $cdate = $('<span>', {
'class': 'cp-app-drive-element-ctime cp-app-drive-element-list'
}).text(getDate(data.ctime));
$element.append($type).append($adate).append($cdate);
};
var _addOwnership = function ($span, $state, data) {
if (data && Array.isArray(data.owners) && data.owners.indexOf(edPublic) !== -1) {
var $owned = $ownedIcon.clone().appendTo($state);
@ -1914,6 +1956,9 @@ define([
if (!manager.isFile(element)) { return; }
var data = manager.getFileData(element);
if (data.static) {
return addStaticData(element, $element, data);
}
if (!Object.keys(data).length) {
return true;
@ -2124,7 +2169,9 @@ define([
$icon = manager.isFolderEmpty(root[key]) ? $folderEmptyIcon.clone() : $folderIcon.clone();
$icon.css("color", getFolderColor(path.concat(elPath)));
}
var classes = restrictedClass + roClass + liClass;
var staticClass = manager.isStaticFile(element) ? '.cp-app-drive-static' : '';
var classes = restrictedClass + roClass + liClass + staticClass;
var $element = $(h('li.cp-app-drive-element.cp-app-drive-element-row' + classes, {
draggable: true
}));
@ -2289,7 +2336,8 @@ define([
var createTitle = function ($container, path, noStyle) {
if (!path || path.length === 0) { return; }
var isTrash = manager.isPathIn(path, [TRASH]);
if (APP.mobile() && !noStyle) { // noStyle means title in search result
// we assume that users viewing shared folders may want to see the "bread-crumb"
if (!APP.newSharedFolder && APP.mobile() && !noStyle) { // noStyle means title in search result
return $container;
}
var isVirtual = virtualCategories.indexOf(path[0]) !== -1;
@ -2458,8 +2506,7 @@ define([
setViewMode(viewMode || 'grid');
showMode(viewMode);
$button.click(function (e) {
console.error(e);
$button.click(function () {
var viewMode = getViewMode();
var newViewMode = getOppositeViewMode(viewMode);
setViewMode(newViewMode);
@ -2685,6 +2732,74 @@ define([
});
$input.click();
};
var showLinkModal = function () {
var name, url;
var warning = h('div.alert.alert-warning', [
h('i.fa.fa-exclamation-triangle'),
h('span', Messages.fm_link_warning)
]);
var content = h('p', [
h('label', {for: 'cp-app-drive-link-name'}, Messages.fm_link_name),
name = h('input#cp-app-drive-link-name', { autocomplete: 'off', placeholder: Messages.fm_link_name_placeholder }),
h('label', {for: 'cp-app-drive-link-url'}, Messages.fm_link_url),
url = h('input#cp-app-drive-link-url', { type: 'url', autocomplete: 'off', placeholder: Messages.form_input_ph_url }),
warning,
]);
var protocolPattern = /https*:\/\//;
var fragmentPattern = /#.*$/;
var setNamePlaceholder = function (val) {
var temp = val.replace(protocolPattern, '').replace(fragmentPattern, '').trim().slice(0, 48);
if (!protocolPattern.test(val) || !temp) {
temp = Messages.fm_link_name_placeholder;
}
name.setAttribute('placeholder', temp);
};
var $warning = $(warning).hide();
var $url = $(url).on('change keypress keyup keydown', function () {
var v = $url.val().trim();
if (v.length > 200) {
$warning.show();
return;
}
setNamePlaceholder(v);
$warning.hide();
});
var buttons = [{
className: 'cancel',
name: Messages.cancelButton,
onClick: function () {},
keys: [27]
}];
buttons.push({
className: 'primary',
// We may want to use a new key here
iconClass: '.fa.fa-plus',
name: Messages.tag_add,
onClick: function () {
var $name = $(name);
var n = $name.val().trim() || $name.attr('placeholder');
var u = $url.val().trim();
if (!n || !u) { return true; }
if (!Util.isValidURL(u)) {
// XXX 4.10.0 add style for invalid input? input:invalid
UI.warn(Messages.fm_link_invalid);
return true;
}
manager.addLink(currentPath, {
name: n,
url: u
}, refresh);
Feedback.send("LINK_CREATED");
},
keys: [13]
});
var m = UI.dialog.customModal(content, {
buttons: buttons
});
UI.openCustomModal(m);
};
var addNewPadHandlers = function ($block, isInRoot) {
// Handlers
if (isInRoot) {
@ -2713,6 +2828,7 @@ define([
}
$block.find('a.cp-app-drive-new-fileupload, li.cp-app-drive-new-fileupload').click(showUploadFilesModal);
$block.find('a.cp-app-drive-new-folderupload, li.cp-app-drive-new-folderupload').click(showUploadFolderModal);
$block.find('a.cp-app-drive-new-link, li.cp-app-drive-new-link').click(showLinkModal);
}
$block.find('a.cp-app-drive-new-doc, li.cp-app-drive-new-doc')
.click(function () {
@ -2756,6 +2872,12 @@ define([
});
}
options.push({tag: 'hr'});
options.push({
tag: 'a',
attributes: {'class': 'cp-app-drive-new-link'},
content: $('<div>').append(getIcon('link')).html() + Messages.fm_link_new
});
options.push({tag: 'hr'});
}
getNewPadTypes().forEach(function (type) {
var attributes = {
@ -3072,6 +3194,13 @@ define([
$elementFolderUpload.append($('<span>', {'class': 'cp-app-drive-new-name'})
.text(Messages.uploadFolderButton));
}
// Link
var $elementLink = $('<li>', {
'class': 'cp-app-drive-new-link cp-app-drive-element-row ' +
'cp-app-drive-element-grid'
}).prepend(getIcon('link')).appendTo($container);
$elementLink.append($('<span>', {'class': 'cp-app-drive-new-name'})
.text(Messages.fm_link_type));
}
// Pads
getNewPadTypes().forEach(function (type) {
@ -3147,7 +3276,8 @@ define([
if (APP.$burnThisDrive) {
APP.toolbar.$bottomR.append(APP.$burnThisDrive);
}
collapseTreeButton();
// this button is not useful for unregistered users who do not have a tree worth looking at
if (APP.loggedIn) { collapseTreeButton(); }
return $toolbar;
};
@ -3477,6 +3607,7 @@ define([
var path = paths[0];
if (manager.isPathIn(path, [TRASH])) { return; }
if (!file.channel) { file.channel = id; }
if (channels.indexOf(file.channel) !== -1) { return; }
channels.push(file.channel);
@ -4480,8 +4611,9 @@ define([
password: data.password
},
isTemplate: paths[0].path[0] === 'template',
title: data.title,
title: data.title || data.name,
sharedFolder: sf,
static: data.static ? data.href : undefined,
common: common
};
if (padType === 'file') {
@ -4499,6 +4631,20 @@ define([
data = manager.getSharedFolderData(el);
}
if (!data) { return; }
if (data.static) {
sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "addLink",
teamId: -1,
data: {
name: data.name,
href: data.href,
path: ['root']
}
}, function () {
UI.log(Messages.saved);
});
return;
}
sframeChan.query('Q_STORE_IN_TEAM', {
href: data.href || data.rohref,
password: data.password,
@ -4537,6 +4683,9 @@ define([
}
else if ($this.hasClass("cp-app-drive-context-newdoc")) {
var ntype = $this.data('type') || 'pad';
if (ntype === 'link') {
return void showLinkModal();
}
var path2 = manager.isPathIn(currentPath, [TRASH]) ? '' : currentPath;
openIn(ntype, path2, APP.team);
}

View File

@ -90,7 +90,11 @@ define([
setTimeout(w);
});
if (res && /^http/.test(res)) {
href = Hash.getRelativeHref(res);
var _href = Hash.getRelativeHref(res);
if (_href) { href = _href; }
else {
href = res;
}
setTimeout(w);
return;
}
@ -109,6 +113,7 @@ define([
if (mailbox.notifications && mailbox.curvePublic) {
common.mailbox.sendTo("SHARE_PAD", {
href: href,
isStatic: Boolean(config.static),
password: config.password,
isTemplate: config.isTemplate,
name: myName,
@ -119,6 +124,9 @@ define([
channel: mailbox.notifications,
curvePublic: mailbox.curvePublic
});
if (config.static) {
Feedback.send("LINK_SHARED_WITH_CONTACT");
}
return;
}
}
@ -137,6 +145,21 @@ define([
});
return;
}
if (config.static) {
common.getSframeChannel().query("Q_DRIVE_USEROBJECT", {
cmd: "addLink",
teamId: team.id,
data: {
name: title,
href: href,
path: ['root']
}
}, function () {
UI.log(Messages.saved);
});
Feedback.send("LINK_ADDED_TO_DRIVE");
return;
}
sframeChan.query('Q_STORE_IN_TEAM', {
href: href,
password: config.password,
@ -346,6 +369,9 @@ define([
] : [
UI.createCheckbox('cp-share-embed', Messages.share_linkEmbed, false, { mark: {tabindex:1} }),
];
if (opts.static) { linkContent = []; }
linkContent.push(h('div.cp-spacer'));
linkContent.push(UI.dialog.selectableArea('', { id: 'cp-share-link-preview', tabindex: 1, rows:3}));
@ -361,7 +387,7 @@ define([
// warning about sharing links
// when sharing a version hash, there is a similar warning and we want
// to avoid alert fatigue
if (!opts.versionHash) {
if (!opts.versionHash && !opts.static) {
var localStore = window.cryptpadStore;
var dismissButton = h('span.fa.fa-times');
var shareLinkWarning = h('div.alert.alert-warning.dismissable',
@ -405,6 +431,10 @@ define([
var v = opts.getLinkValue({
embed: Util.isChecked($link.find('#cp-share-embed'))
});
if (opts.static) {
common.openUnsafeURL(v);
return true;
}
window.open(v);
return true;
},
@ -562,6 +592,7 @@ define([
});
};
opts.getLinkValue = function (initValue, cb) {
if (opts.static) { return opts.static; }
var val = initValue || {};
var edit = val.edit !== undefined ? val.edit : Util.isChecked($rights.find('#cp-share-editable-true'));
var embed = val.embed;
@ -686,7 +717,7 @@ define([
opts.access = true; // Allow the use of the modal even if the pad is not stored
var hashes = opts.hashes;
if (!hashes || (!hashes.editHash && !hashes.viewHash)) { return; }
if (!hashes || (!hashes.editHash && !hashes.viewHash && !opts.static)) { return; }
var teams = getEditableTeams(common, opts);
opts.teams = teams;
@ -705,19 +736,23 @@ define([
var $rights = opts.$rights = getRightsHeader(common, opts);
var resetTab = function () {
if (opts.static) { return; }
$rights.show();
$rights.find('label.cp-radio').show();
};
var onShowEmbed = function () {
if (opts.static) { return; }
$rights.find('#cp-share-bar').closest('label').hide();
$rights.find('input[type="radio"]:enabled').first().prop('checked', 'checked');
$rights.find('input[type="radio"]').trigger('change');
};
var onShowContacts = function () {
if (opts.static) { return; }
if (!hasFriends || priv.offline) {
$rights.hide();
}
};
if (opts.static) { $rights.hide(); }
var contactsActive = hasFriends && !priv.offline;
var tabs = [{
@ -732,13 +767,16 @@ define([
title: Messages.share_linkCategory,
icon: "fa fa-link",
active: !contactsActive,
}, {
getTab: getEmbedTab,
title: Messages.share_embedCategory,
icon: "fa fa-code",
onShow: onShowEmbed,
onHide: resetTab
}];
if (!opts.static) {
tabs.push({
getTab: getEmbedTab,
title: Messages.share_embedCategory,
icon: "fa fa-code",
onShow: onShowEmbed,
onHide: resetTab
});
}
Modal.getModal(common, opts, tabs, function (err, modal) {
// Hide the burn-after-reading option by default
var $modal = $(modal);

View File

@ -92,6 +92,10 @@ define([
(type === 'file' ? 'notification_fileShared' : // Msg.notification_fileSharedTeam
'notification_padShared'); // Msg.notification_padSharedTeam
if (msg.content.isStatic) {
key = 'notification_linkShared'; // Msg.notification_linkShared;
}
var teamNotification = /^team-/.test(data.type) && Number(data.type.slice(5));
var teamName = '';
if (teamNotification) {
@ -109,6 +113,15 @@ define([
return Messages._getKey(key, [name, title, teamName]);
};
content.handler = function() {
if (msg.content.isStatic) {
UIElements.displayOpenLinkModal(common, {
curve: msg.author,
href: msg.content.href,
name: name,
title: title
}, defaultDismiss(common, data));
return;
}
var obj = {
p: msg.content.isTemplate ? ['template'] : undefined,
t: teamNotification || undefined,

View File

@ -1306,9 +1306,14 @@ define([
getAllStores().forEach(function (s) {
s.manager.getSecureFilesList(where).forEach(function (obj) {
var data = obj.data;
if (channels.indexOf(data.channel) !== -1) { return; }
if (channels.indexOf(data.channel || data.id) !== -1) { return; }
var id = obj.id;
if (data.channel) { channels.push(data.channel); }
if (data.channel) { channels.push(data.channel || data.id); }
// Only include static links if "link" is requested
if (data.static) {
if (types.indexOf('link') !== -1) { list[id] = data; }
return;
}
var parsed = Hash.parsePadUrl(data.href || data.roHref);
if ((!types || types.length === 0 || types.indexOf(parsed.type) !== -1) &&
!isFiltered(parsed.type, data)) {
@ -2053,8 +2058,17 @@ define([
} catch (e) {
console.error(e);
}
// Tell all the owners that the pad was deleted from the server
var curvePublic = store.proxy.curvePublic;
var curvePublic;
try {
// users in noDrive mode don't have a proxy and
// unregistered users don't have a curvePublic
curvePublic = store.proxy.curvePublic;
} catch (err) {
console.error(err);
return;
}
m.forEach(function (obj) {
var mb = JSON.parse(obj);
if (mb.curvePublic === curvePublic) { return; }

View File

@ -97,7 +97,7 @@ define([
var checkCheckpoints = function (array) {
if (!Array.isArray(array)) { return; }
// Keep the last 100 messages
if (array.length > 100) {
if (array.length > 100) { // XXX 4.10.0
array.splice(0, array.length - 100);
}
// Remove every message before the first checkpoint

View File

@ -238,8 +238,9 @@ define([
// content.name, content.title, content.href, content.password
if (isMuted(ctx, data)) { return void cb(true); }
var channel = Hash.hrefToHexChannelId(content.href, content.password);
// if the shared content is a 'link' then we can't use the channel to deduplicate notifications
// use href instead.
var channel = content.isStatic ? content.href : Hash.hrefToHexChannelId(content.href, content.password);
var parsed = Hash.parsePadUrl(content.href);
var mode = parsed.hashData && parsed.hashData.mode || 'n/a';

View File

@ -195,7 +195,7 @@ define([
Pinpad.create(ctx.store.network, data, function (e, call) {
if (e) { return void cb(e); }
team.rpc = call;
team.onRpcReadyEvt.fire();
if (team && team.onRpcReadyEvt) { team.onRpcReadyEvt.fire(); }
cb();
}, Cache);
});

View File

@ -20,6 +20,7 @@ define([
var ROOT = exp.ROOT;
var FILES_DATA = exp.FILES_DATA;
var STATIC_DATA = exp.STATIC_DATA;
var OLD_FILES_DATA = exp.OLD_FILES_DATA;
var UNSORTED = exp.UNSORTED;
var TRASH = exp.TRASH;
@ -78,6 +79,14 @@ define([
files[FILES_DATA][id] = data;
cb(null, id);
};
exp.pushLink = function (_data, cb) {
if (typeof cb !== "function") { cb = function () {}; }
if (readOnly) { return void cb('EFORBIDDEN'); }
var id = Util.createRandomInteger();
var data = clone(_data);
files[STATIC_DATA][id] = data;
cb(null, id);
};
exp.pushSharedFolder = function (_data, cb) {
if (typeof cb !== "function") { cb = function () {}; }
@ -136,7 +145,7 @@ define([
var filesList = exp.getFiles([ROOT, 'hrefArray', TRASH]);
var toClean = [];
exp.getFiles([FILES_DATA, SHARED_FOLDERS]).forEach(function (id) {
exp.getFiles([FILES_DATA, SHARED_FOLDERS, STATIC_DATA]).forEach(function (id) {
if (filesList.indexOf(id) === -1) {
var fd = exp.isSharedFolder(id) ? files[SHARED_FOLDERS][id] : exp.getFileData(id);
var channelId = fd.channel;
@ -146,6 +155,8 @@ define([
if (exp.isSharedFolder(id)) {
delete files[SHARED_FOLDERS][id];
if (config.removeProxy) { config.removeProxy(id); }
} else if (files[STATIC_DATA][id]) {
delete files[STATIC_DATA][id];
} else {
spliceFileData(id);
}
@ -242,6 +253,12 @@ define([
id = Number(id);
// Find and maybe update existing pads with the same channel id
var d = data[id];
// If we were given a static link, copy to STATIC_DATA
if (d.static) {
delete d.static;
files[STATIC_DATA][id] = d;
return;
}
// If we were given an edit link, encrypt its value if needed
if (d.href) { d.href = exp.cryptor.encrypt(d.href); }
var found = false;
@ -398,7 +415,7 @@ define([
if (!loggedIn && !config.testMode) { return; }
id = Number(id);
var data = files[FILES_DATA][id] || files[SHARED_FOLDERS][id];
var data = files[FILES_DATA][id] || files[STATIC_DATA][id] || files[SHARED_FOLDERS][id];
if (!data || typeof(data) !== "object") { return; }
var newPath = path, parentEl;
if (path && !Array.isArray(path)) {
@ -599,13 +616,18 @@ define([
var element = elem || files[ROOT];
if (!element) { return console.error("Invalid element in root"); }
var nbMetadataFolders = 0;
// caching this variables saves a lot of hashmap lookups in this loop
var static_data = files[STATIC_DATA];
var files_data = files[FILES_DATA];
var element_el;
for (var el in element) {
if (element[el] === null) {
element_el = element[el];
if (element_el === null) {
console.error('element[%s] is null', el);
delete element[el];
continue;
}
if (exp.isFolderData(element[el])) {
if (exp.isFolderData(element_el)) {
if (nbMetadataFolders !== 0) {
debug("Multiple metadata files in folder");
delete element[el];
@ -613,30 +635,30 @@ define([
nbMetadataFolders++;
continue;
}
if (!exp.isFile(element[el], true) && !exp.isFolder(element[el])) {
debug("An element in ROOT was not a folder nor a file. ", element[el]);
if (!exp.isFile(element_el, true) && !exp.isFolder(element_el)) {
debug("An element in ROOT was not a folder nor a file. ", element_el);
delete element[el];
continue;
}
if (exp.isFolder(element[el])) {
fixRoot(element[el]);
if (exp.isFolder(element_el)) {
fixRoot(element_el);
continue;
}
if (typeof element[el] === "string") {
if (typeof element_el === "string") {
// We have an old file (href) which is not in filesData: add it
var id = Util.createRandomInteger();
var key = Hash.createChannelId();
files[FILES_DATA][id] = {
href: exp.cryptor.encrypt(element[el]),
files_data[id] = {
href: exp.cryptor.encrypt(element_el),
filename: el
};
element[key] = id;
delete element[el];
}
if (typeof element[el] === "number") {
var data = files[FILES_DATA][element[el]];
if (typeof element_el === "number") {
var data = files_data[element_el] || static_data[element_el];
if (!data) {
debug("An element in ROOT doesn't have associated data", element[el], el);
debug("An element in ROOT doesn't have associated data", element_el, el);
delete element[el];
}
}
@ -845,6 +867,26 @@ define([
toClean.forEach(function (id) {
spliceFileData(id);
});
// make sure that links are displayed at least once in your drive if you are going to keep them
var sd = files[STATIC_DATA];
var toCleanSD = [];
for (var id2 in sd) {
id2 = Number(id2);
var el2 = sd[id2];
if (!el2 || typeof(el2) !== "object" || !el2.href) {
toCleanSD.push(id2);
continue;
}
if ((loggedIn || config.testMode) && rootFiles.indexOf(id2) === -1) {
toCleanSD.push(id2);
continue;
}
}
var spliceSD = function (id) {
if (readOnly) { return; }
delete files[STATIC_DATA][id];
};
toCleanSD.forEach(spliceSD);
};
var fixSharedFolders = function () {
if (sharedFolder) { return; }
@ -892,6 +934,12 @@ define([
}
}
};
var fixStaticData = function () {
if (!Util.isObject(files[STATIC_DATA])) {
debug("STATIC_DATA was not an object");
files[STATIC_DATA] = {};
}
};
var fixDrive = function () {
@ -900,6 +948,7 @@ define([
});
};
fixStaticData();
fixRoot();
fixTrashRoot();
fixTemplate();

View File

@ -22,11 +22,11 @@ define([
// a cached version
if (Env.folders[id].offline && !lm.cache) {
Env.folders[id].offline = false;
if (Env.folders[id].userObject.fixFiles) { Env.folders[id].userObject.fixFiles(); }
Env.Store.refreshDriveUI();
}
return;
}
if (Env.folders[id]) { console.warn(Env.folders[id]); }
var cfg = getConfig(Env);
cfg.sharedFolder = true;
cfg.id = id;
@ -584,6 +584,24 @@ define([
});
});
};
// Add a link
var _addLink = function (Env, data, cb) {
data = data || {};
var resolved = _resolvePath(Env, data.path);
if (!resolved || !resolved.userObject) { return void cb({error: 'E_NOTFOUND'}); }
var uo = resolved.userObject;
var now = +new Date();
uo.pushLink({
name: data.name,
href: data.href,
atime: now,
ctime: now
}, function (e, id) {
if (e) { return void cb({error: e}); }
uo.add(id, resolved.path);
Env.onSync(cb);
});
};
var _restoreSharedFolder = function (Env, _data, cb) {
var fId = _data.id;
@ -1019,35 +1037,40 @@ define([
});
};
var _updateStaticAccess = function (Env, id, cb) {
var uo = _getUserObjectFromId(Env, id);
var sd = uo.getFileData(id, true);
sd.atime = +new Date();
Env.onSync(cb);
};
var COMMANDS = {
move: _move,
restore: _restore,
addFolder: _addFolder,
addSharedFolder: _addSharedFolder,
addLink: _addLink,
restoreSharedFolder: _restoreSharedFolder,
convertFolderToSharedFolder: _convertFolderToSharedFolder,
delete: _delete,
deleteOwned: _deleteOwned,
emptyTrash: _emptyTrash,
rename: _rename,
setFolderData: _setFolderData,
updateStaticAccess: _updateStaticAccess,
};
var onCommand = function (Env, cmdData, cb) {
var cmd = cmdData.cmd;
var data = cmdData.data || {};
switch (cmd) {
case 'move':
_move(Env, data, cb); break;
case 'restore':
_restore(Env, data, cb); break;
case 'addFolder':
_addFolder(Env, data, cb); break;
case 'addSharedFolder':
_addSharedFolder(Env, data, cb); break;
case 'restoreSharedFolder':
_restoreSharedFolder(Env, data, cb); break;
case 'convertFolderToSharedFolder':
_convertFolderToSharedFolder(Env, data, cb); break;
case 'delete':
_delete(Env, data, cb); break;
case 'deleteOwned':
_deleteOwned(Env, data, cb); break;
case 'emptyTrash':
_emptyTrash(Env, data, cb); break;
case 'rename':
_rename(Env, data, cb); break;
case 'setFolderData':
_setFolderData(Env, data, cb); break;
default:
cb();
var method = COMMANDS[cmd];
if (typeof(method) === 'function') {
return void method(Env, data, cb);
}
// if the command was not handled then call back
cb();
};
// Set the value everywhere the given pad is stored (main and shared folders)
@ -1129,8 +1152,8 @@ define([
data: uo.getFileData(id)
};
}).filter(function (d) {
if (channels.indexOf(d.data.channel) === -1) {
channels.push(d.data.channel);
if (channels.indexOf(d.data.channel || d.id) === -1) {
channels.push(d.data.channel || d.id);
return true;
}
});
@ -1233,7 +1256,10 @@ define([
Array.prototype.push.apply(result, sfChannels);
}
return result;
return result.filter(function (channel) {
if (typeof(channel) !== 'string') { return; }
return [32, 48].indexOf(channel.length) !== -1;
});
};
var addPad = function (Env, path, pad, cb) {
@ -1383,6 +1409,16 @@ define([
}
}, cb);
};
var addLinkInner = function (Env, path, data, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "addLink",
data: {
path: path,
name: data.name,
href: data.url
}
}, cb);
};
var restoreSharedFolderInner = function (Env, fId, password, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "restoreSharedFolder",
@ -1433,6 +1469,14 @@ define([
}, cb);
};
var updateStaticAccessInner = function (Env, id, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "updateStaticAccess",
data: id
}, cb);
};
/* Tools */
var findChannels = _findChannels;
@ -1450,6 +1494,11 @@ define([
return String(uo.getTitle(id, type));
};
var isStaticFile = function (Env, id) {
var uo = _getUserObjectFromId(Env, id);
return uo.isStaticFile(id);
};
var isReadOnlyFile = function (Env, id) {
var uo = _getUserObjectFromId(Env, id);
return uo.isReadOnlyFile(id);
@ -1491,7 +1540,7 @@ define([
var files = [];
var userObjects = _getUserObjects(Env);
userObjects.forEach(function (uo) {
var data = uo.getFiles([UserObject.FILES_DATA]).map(function (id) {
var data = uo.getFiles([UserObject.FILES_DATA, UserObject.STATIC_DATA]).map(function (id) {
return [Number(id), uo.getFileData(id)];
});
Array.prototype.push.apply(files, data);
@ -1608,17 +1657,20 @@ define([
emptyTrash: callWithEnv(emptyTrashInner),
addFolder: callWithEnv(addFolderInner),
addSharedFolder: callWithEnv(addSharedFolderInner),
addLink: callWithEnv(addLinkInner),
restoreSharedFolder: callWithEnv(restoreSharedFolderInner),
convertFolderToSharedFolder: callWithEnv(convertFolderToSharedFolderInner),
delete: callWithEnv(deleteInner),
deleteOwned: callWithEnv(deleteOwnedInner),
restore: callWithEnv(restoreInner),
setFolderData: callWithEnv(setFolderDataInner),
updateStaticAccess: callWithEnv(updateStaticAccessInner),
// Tools
getFileData: callWithEnv(getFileData),
find: callWithEnv(find),
getTitle: callWithEnv(getTitle),
isReadOnlyFile: callWithEnv(isReadOnlyFile),
isStaticFile: callWithEnv(isStaticFile),
getFiles: callWithEnv(getFiles),
search: callWithEnv(search),
getRecentPads: callWithEnv(getRecentPads),

View File

@ -733,11 +733,20 @@ define([
if (!common.isLoggedIn()) { return; }
$embedButton = common.createButton('mediatag', true).click(function () {
var cfg = {
types: ['file'],
types: ['file', 'link'],
where: ['root']
};
if ($embedButton.data('filter')) { cfg.filter = $embedButton.data('filter'); }
common.openFilePicker(cfg, function (data) {
// Embed links
if (data.static) {
var a = h('a', {
href: data.href
}, data.name);
mediaTagEmbedder($(a), data);
return;
}
// Embed files
if (data.type !== 'file') {
console.log("Unexpected data type picked " + data.type);
return;

View File

@ -1925,7 +1925,6 @@ define([
var cryptputCfg = $.extend(true, {}, rtConfig, {password: password});
if (data.templateContent) {
Cryptget.put(currentPad.hash, JSON.stringify(data.templateContent), function () {
console.error(arguments);
startRealtime();
cb();
}, cryptputCfg);
@ -2004,6 +2003,8 @@ define([
sframeChan.on('EV_BURN_AFTER_READING', function () {
startRealtime();
// feedback fails for users in noDrive mode
Utils.Feedback.send("BURN_AFTER_READING", Boolean(cfg.noDrive));
});
sframeChan.ready();

View File

@ -23,6 +23,12 @@ define([
var $title;
exp.setToolbar = function (toolbar) {
$title = toolbar && (toolbar.title || toolbar.pageTitle);
if ($title && exp.defaultTitle) {
var md = metadataMgr.getMetadata();
$title.find('input').prop('placeholder', md.defaultTitle);
$title.find('span.cp-toolbar-title-value').text(md.title || md.defaultTitle);
$title.find('input').val(md.title || md.defaultTitle);
}
};
exp.getTitle = function () { return exp.title; };

View File

@ -867,10 +867,6 @@ MessengerUI, Messages, Pages) {
'class': "cp-toolbar-link-logo"
}).append(UIElements.getSvgLogo());
/*.append($('<img>', {
//src: '/customize/images/logo_white.png?' + ApiConfig.requireConf.urlArgs
src: '/customize/favicon/main-favicon.png?' + ApiConfig.requireConf.urlArgs
}));*/
var onClick = function (e) {
e.preventDefault();
if (e.ctrlKey) {

View File

@ -13,7 +13,8 @@
"todo": "Tasques",
"contacts": "Contactes",
"sheet": "Full de càlcul",
"teams": "Equips"
"teams": "Equips",
"form": "Formulari"
},
"button_newpad": "Nou document",
"button_newcode": "Nova pàgina de codi",
@ -28,18 +29,18 @@
"padNotPinned": "Aquest document caducarà després de 3 mesos d'inactivitat, {0}connecteu-vos{1} o {2}registreu-vos{3} per conservar-lo.",
"anonymousStoreDisabled": "L'administració d'aquesta instància de CryptPad ha desactivat l'emmagatzematge pels comptes anònims. Cal que inicieu la sessió per utilitzar el CryptDrive.",
"expiredError": "Aquest document ha caducat i ja no està disponible.",
"deletedError": "La persona que va crear aquest document l'ha esborrat i ja no està disponible.",
"deletedError": "Aquest document ha estat esborrat i ja no està disponible.",
"inactiveError": "Donada la seva inactivitat, aquest document s'ha esborrat. Premeu Esc per crear un nou document.",
"chainpadError": "Hi ha hagut un error crític mentre s'actualitzava el vostre contingut. Aquesta pàgina es manté en mode només de lectura per assegurar que no perdreu el que ja heu fet.<br>Premeu <em>Esc</em> per continuar veient aquest document o torneu a carregar la pàgina per provar de continuar editant-lo.",
"invalidHashError": "El document que heu demanat té una adreça URL no vàlida.",
"errorCopy": " Encara podeu accedir al contingut prement <em>Esc</em>.<br>Un cop tanqueu aquesta finestra no hi podreu tornar a accedir.",
"errorCopy": " Encara podeu usar la versió actual en mode \"només lectura\" prement <em>Esc</em>.",
"errorRedirectToHome": "Premeu <em>Esc</em> per tornar al vostre CryptDrive.",
"newVersionError": "Hi ha una nova versió disponible de CryptPad.<br><a href='#'>Torneu a carregar</a> la pàgina per utilitzar la versió nova o premeu Esc per accedir al vostre contingut en mode <b>fora de línia</b>.",
"loading": "Carregant...",
"error": "Error",
"saved": "Desat",
"deleted": "Esborrat",
"deletedFromServer": "Document esborrat del servidor",
"deletedFromServer": "Document destruït",
"mustLogin": "Cal que inicieu la sessió per accedir a aquesta pàgina",
"disabledApp": "Aquesta aplicació està dehabilitada. Per a més informació, contacteu l'administració d'aquest CryptPad.",
"realtime_unrecoverableError": "Hi ha hagut un error irreparable. Cliqueu D'acord per tornar a carregar la pàgina.",
@ -93,7 +94,7 @@
"newButton": "Nou/Nova",
"newButtonTitle": "Crea un nou document",
"uploadButton": "Carregar fitxers",
"uploadButtonTitle": "Carrega un fitxer nou a la carpeta actual",
"uploadButtonTitle": "Carrega un fitxer nou al vostre CryptDrive",
"saveTemplateButton": "Desa com una plantilla",
"saveTemplatePrompt": "Trieu un títol per la plantilla",
"templateSaved": "Plantilla desada!",
@ -128,7 +129,7 @@
"filePicker_description": "Trieu un fitxer del vostre CryptDrive per incrustar-lo o carregueu-ne un de nou",
"filePicker_filter": "Filtra els fitxers pel nom",
"tags_title": "Etiquetes (només vostres)",
"tags_add": "Actualitza les etiquetes d'aquesta pàgina",
"tags_add": "Actualitza les etiquetes dels documents seleccionats",
"tags_notShared": "Les vostres etiquetes no es comparteixen amb altres persones usuàries",
"tags_duplicate": "Etiquetes duplicades: {0}",
"tags_noentry": "No podeu etiquetar un document esborrat!",
@ -155,12 +156,12 @@
"help_button": "Ajuda",
"historyText": "Historial",
"historyButton": "Mostra l'historial del document",
"history_next": "La versió més nova",
"history_prev": "La versió més antiga",
"history_next": "Següent versió",
"history_prev": "Versió anterior",
"history_loadMore": "Carrega més historial",
"history_closeTitle": "Tanca l'historial",
"history_restoreTitle": "Restaura la versió seleccionada del document",
"history_restorePrompt": "Segur que voleu reemplaçar la versió actual del document per la que es mostra?",
"history_restorePrompt": "De debò voleu substituir la versió actual del document per la versió que es mostra?",
"history_restoreDone": "S'ha restaurat el document",
"openLinkInNewTab": "Obre l'enllaç en una pestanya nova",
"pad_mediatagTitle": "Configuració de l'Etiqueta Multimèdia",
@ -252,7 +253,7 @@
"fm_sharedFolderName": "Carpeta compartida",
"fm_searchPlaceholder": "Cercant...",
"fm_newButton": "Nou",
"fm_newButtonTitle": "Crea un nou document o carpeta, importa un fitxer a la carpeta actual",
"fm_newButtonTitle": "Crea un nou document o carpeta, importa un fitxer a la carpeta actual.",
"fm_newFolder": "Carpeta nova",
"fm_newFile": "Document de text nou",
"fm_folder": "Carpeta",
@ -269,8 +270,8 @@
"fm_openParent": "Veure a la carpeta",
"fm_noname": "Document sense títol",
"fm_emptyTrashDialog": "De debò voleu buidar la paperera?",
"fm_removeSeveralPermanentlyDialog": "De debò voleu suprimir permanentment aquests {0} elements del vostre CryptDrive?",
"fm_removePermanentlyDialog": "De debò voleu suprimir permanentment aquest element del vostre CryptDrive?",
"fm_removeSeveralPermanentlyDialog": "De debò voleu suprimir aquests {0} elements de la vostra unitat? Es mantindran a les unitats de qui els hagis desat.",
"fm_removePermanentlyDialog": "De debò voleu suprimir permanentment aquest element de la vostra unitat? Es mantindrà a les unitats de qui l'hagi desat.",
"fm_deleteOwnedPad": "De debò voleu suprimir permanentment aquest document del servidor?",
"fm_deleteOwnedPads": "De debò voleu suprimir permanentment aquests documents del servidor?",
"fm_restoreDialog": "De debò voleu restaurar {0} a la seva ubicació prèvia?",
@ -282,7 +283,7 @@
"fm_info_template": "Conté tots els documents desats com plantilles i que podeu reutilitzar quan vulgueu crear un nou document.",
"fm_info_recent": "Aquests documents s'han modificat o obert darrerament, per vós o per alguna persona col·laboradora.",
"fm_info_trash": "Buideu la paperera per alliberar espai al vostre CryptDrive.",
"fm_info_anonymous": "No heu iniciat la sessió, per tant, els vostres documents caducaran d'aquí a 3 mesos. Es desen al vostre navegador, per tant, si netegeu el vostre historial podríeu perdre'ls.<br><a href=\"/register/\">Registreu-vos</a> o <a href=\"/login/\">Inicieu la sessió</a> per mantenir-los accessibles.<br>",
"fm_info_anonymous": "No heu iniciat la sessió, per tant, els vostres documents caducaran d'aquí a {0} dies. Si esborreu l'historial del vostre navegador podríeu perdre'ls.<br><a href=\"/register/\">Registreu-vos</a> (no es demanen dades personals) o <a href=\"/login/\">Inicieu la sessió</a> per desar-los indefinidament a la vostra unitat. <a href=\"#docs\">Llegiu més sobre els comptes registrats</a>",
"fm_info_sharedFolder": "Aquesta és una carpeta compartida. No heu iniciat cap sessió, pel que només podeu accedir en mode només de lectura.<br><a href=\"/register/\">Registreu-vos</a> o <a href=\"/login/\">Inicieu la sessió</a> per poder importar-ho al vostre CryptDrive i modificar-ho.",
"fm_info_owned": "Es documents que es mostren són de la vostra propietat. Això vol dir que podeu eliminar-los permanentment del servidor quan vulgueu. Si ho feu, la resta de persones no podran accedir-hi mai més.",
"fm_error_cantPin": "Error intern del servidor. Si us plau, torneu a garregar la pàgina i torneu a provar-ho.",
@ -307,9 +308,9 @@
"fc_open": "Obre",
"fc_open_ro": "Obre (només de lectura)",
"fc_delete": "Desplaça a la paperera",
"fc_delete_owned": "Elimina del servidor",
"fc_delete_owned": "Destrueix",
"fc_restore": "Restaura",
"fc_remove": "Suprimeix del vostre CryptDrive",
"fc_remove": "Suprimeix",
"fc_remove_sharedfolder": "Suprimeix",
"fc_empty": "Buida la paperera",
"fc_prop": "Propietats",
@ -330,16 +331,16 @@
"login_invalUser": "Cal introduir l'identificador",
"login_invalPass": "Cal introduir la contrasenya",
"login_unhandledError": "Hi ha hagut un error inesperat :(",
"register_importRecent": "Importeu els documents de la vostra sessió anònima",
"register_importRecent": "Importa documents de la vostra sessió no registrada",
"register_acceptTerms": "Accepto les <a>condicions del servei</a>",
"register_passwordsDontMatch": "Les contrasenyes no coincideixen!",
"register_passwordTooShort": "Les contrasenyes han de tenir, com a mínim, {0} caràcters.",
"register_mustAcceptTerms": "Cal que accepteu les condicions del servei.",
"register_whyRegister": "Per què cal registrar-se?",
"register_header": "Us donem la benvinguda a CryptPad",
"register_header": "Registreu-vos",
"register_writtenPassword": "He introduït el meu identificador i la contrasenya, continua",
"register_cancel": "Torna",
"register_warning": "Sense Rastre significa que no podem recuperar les vostres dades si perdeu o oblideu la vostra contrasenya.",
"register_cancel": "Cancel·la",
"register_warning": "Atenció",
"register_alreadyRegistered": "Aquest identificador ja existeix, voleu iniciar la sessió?",
"settings_cat_account": "Compte",
"settings_cat_drive": "CryptDrive",
@ -353,7 +354,7 @@
"settings_backupHint": "Deseu o recupereu tot el contingut del vostre CryptDrive. No es desarà el contingut dels vostres documents, només les claus per accedir-hi.",
"settings_backup": "Còpia de seguretat",
"settings_restore": "Recupera",
"settings_backupHint2": "Descarregueu el contingut actual de tots els vostres documents. Els documents es descarregaran en un format llegible, sempre que el format estigui disponible.",
"settings_backupHint2": "Descarregueu tots els documents. a la vostra unitat. Els documents es descarregaran en un format llegible per altres aplicacions sempre que el format estigui disponible. Quan el format no estigui disponible, els documents es descarregaran en un format llegible per CryptPad.",
"settings_backup2": "Descarrega el meu CryptDrive",
"settings_backup2Confirm": "Això descarregarà tots els documents i fitxers des del vostre CryptDrive. Si voleu continuar, seleccioneu un nom i premeu D'acord",
"settings_exportTitle": "Exporta el vostre CryptDrive",
@ -431,7 +432,7 @@
"settings_codeUseTabs": "Espaiar utilitzant tabulacions (enlloc d'espais)",
"settings_codeFontSize": "Mida de la lletra a l'editor de codi",
"settings_padWidth": "Amplada màxima de l'editor",
"settings_padWidthHint": "Els documents de text enriquit utilitzen, per defecte, l'amplada màxima de la vostra pantalla, fet que pot dificultar la lectura. Aquí podeu reduir l'amplada de l'editor.",
"settings_padWidthHint": "Canvieu entre el mode pàgina (per defecte) que limita l'amplada de l'editor de text i el mode pantalla completa que utilitza tota l'amplada.",
"settings_padWidthLabel": "Redueix l'amplada de l'editor",
"settings_padSpellcheckTitle": "Correcció ortogràfica",
"settings_padSpellcheckHint": "Aquesta opció us permet habilitar la correcció ortogràfica als documents de text. Les errades es subratllaran en vermell i haureu de mantenir apretada la tecla Ctrl o Meta mentre cliqueu el botó dret per veure les opcions correctes.",
@ -473,7 +474,7 @@
"upload_notEnoughSpace": "No hi ha prou espai al CryptDrive per aquest fitxer.",
"upload_notEnoughSpaceBrief": "No hi ha prou espai",
"upload_tooLarge": "Aquest fitxer supera la mida màxima permesa pel vostre compte",
"upload_tooLargeBrief": "El fitxer és massa gran",
"upload_tooLargeBrief": "El fitxer supera el límit de {0}MB",
"upload_choose": "Trieu un fitxer",
"upload_pending": "Pendent",
"upload_cancelled": "Cancel·lat",
@ -505,14 +506,39 @@
"download_step2": "Desxifrant",
"download_step1": "Descarregant",
"download_dl": "Descarrega",
"main_catch_phrase": "El Núvol Coneixement Zero",
"main_catch_phrase": "Utilitats col·laboratives<br> encriptades d'extrem a extrem i de codi obert",
"footer_aboutUs": "Sobre nosaltres",
"about": "Sobre",
"contact": "Contacte",
"blog": "Bloc",
"topbar_whatIsCryptpad": "Què és CryptPad",
"whatis_collaboration": "Col·laboració fàcil i ràpida",
"whatis_title": "Què és CryptPad",
"whatis_collaboration": "Col·laboració privada",
"whatis_title": "Què és CryptPad?",
"terms": "Condicions d'ús",
"privacy": "Privacitat"
"privacy": "Política de privacitat",
"settings_padOpenLinkLabel": "Activa l'obertura directa d'enllaços",
"features": "Característiques",
"features_f_cryptdrive0_note": "Possibilitat d'emmagatzemar els documents visitats al vostre navegador per poder-los obrir més tard",
"features_f_storage0": "Durada d'emmagatzematge limitada",
"settings_padOpenLinkTitle": "Obre els enllaços amb només un clic",
"settings_padOpenLinkHint": "Aquesta opció us permet d'obrir els enllaços dins d'un document de text sense obrir cap finestra",
"features_premium": "Prèmium",
"features_f_core": "Característiques comunes",
"features_f_file0_note": "Veure i descarregar documents compartits per altres membres",
"features_f_anon": "Totes les característiques dels membres anònims",
"features_f_cryptdrive1": "Funcionalitat completa de CryptDrive",
"whatis_drive": "Organització amb CryptPad",
"features_f_cryptdrive0": "Accés limitat a CryptDrive",
"features_f_core_note": "Editar, importar i exportar, historial, llistat de membres, xat",
"features_anon": "No registrat",
"features_f_apps": "Accés a totes les aplicacions",
"features_f_file0": "Obrir documents",
"features_f_storage0_note": "Els documents s'eliminen després de {0} dies d'inactivitat",
"features_registered": "Registrat",
"features_f_anon_note": "Amb funcionalitat addicional",
"features_title": "Característiques",
"features_f_social": "Característiques socials",
"features_f_devices_note": "Accés al CryptDrive des de tot arreu amb el teu compte",
"features_f_devices": "Les teves llibretes en tots els teus dispositius",
"features_f_cryptdrive1_note": "Carpetes, carpetes compartides, models, etiquetes"
}

View File

@ -1332,7 +1332,7 @@
"form_cantFindAnswers": "Deine vorigen Antworten für dieses Formular konnten nicht geladen werden.",
"form_updateWarning": "Trotzdem aktualisieren",
"form_submitWarning": "Trotzdem absenden",
"form_sent": "Gesendet",
"form_sent": "Deine Antwort wurde gesendet",
"form_update": "Aktualisieren",
"form_submit": "Absenden",
"form_type_checkbox": "Mehrfachauswahl",
@ -1368,5 +1368,16 @@
"admin_purpose_public": "Zur Bereitstellung eines kostenlosen Dienstes für die Allgemeinheit",
"resources_learnWhy": "Mehr über die Gründe erfahren",
"team_leaveOwner": "Bitte entferne dich von der Rolle des Eigentümers, bevor du das Teams verlässt. Beachte, dass Teams mindestens einen Eigentümer haben müssen. Bitte füge daher zunächst einen weiteren Eigentümer hinzu, sofern du derzeit der alleinige Eigentümer bist.",
"form_exportCSV": "Als CSV exportieren"
"form_exportCSV": "Als CSV exportieren",
"form_answerAs": "Antworten als",
"notification_openLink": "Du hast einen Link <b>{0}</b> von {1} erhalten:",
"fm_link_warning": "Warnung: URL ist länger als 200 Zeichen",
"notification_linkShared": "{0} hat einen Link mit dir geteilt: <b>{1}</b>",
"fm_link_name": "Bezeichnung des Links",
"fm_link_invalid": "Ungültige URL",
"form_anonName": "Dein Name",
"fm_link_name_placeholder": "Mein Link",
"fm_link_url": "URL",
"fm_link_type": "Link",
"fm_link_new": "Neuer Link"
}

View File

@ -1315,7 +1315,7 @@
"form_updateWarning": "Mettre à jour avec erreurs",
"form_submitWarning": "Envoyer avec erreurs",
"form_delete": "Supprimer",
"form_sent": "Envoyé",
"form_sent": "Votre réponse a été envoyée",
"form_reset": "Effacer",
"form_update": "Mettre à jour",
"form_submit": "Envoyer",
@ -1368,5 +1368,16 @@
"admin_purpose_business": "Usage en entreprise",
"admin_instancePurposeHint": "À quel usage cette instance est-elle destinée ? Votre réponse sera utilisée pour définir la planification de nouvelles fonctionnalités (si votre télémétrie est activée).",
"team_leaveOwner": "Veuillez vous rétrograder de votre rôle de propriétaire avant de quitter l'équipe. Notez que les équipes doivent avoir au moins un propriétaire, veuillez en ajouter un autre avant de poursuivre si vous êtes actuellement le seul propriétaire.",
"form_exportCSV": "Exporter en CSV"
"form_exportCSV": "Exporter en CSV",
"fm_link_invalid": "URL invalide",
"fm_link_warning": "Attention : l'URL dépasse 200 caractères",
"form_answerAs": "Répondre en tant que",
"form_anonName": "Votre nom",
"notification_linkShared": "{0} a partagé un lien avec vous : <b>{1}</b>",
"fm_link_name_placeholder": "Nouveau lien",
"fm_link_url": "URL",
"fm_link_name": "Titre du lien",
"fm_link_type": "Lien",
"fm_link_new": "Nouveau Lien",
"notification_openLink": "Vous avez reçu un lien <b>{0}</b> de {1} :"
}

View File

@ -1,2 +1,9 @@
{
"type": {
"pad": "रिच टेक्स्ट",
"code": "कोड",
"poll": "मतदान",
"kanban": "कानबन"
},
"main_title": "क्रिप्टपैड: शून्य ज्ञान, सहयोगात्मक रीयल टाइम संपादन"
}

View File

@ -1,7 +1,7 @@
{
"common_connectionLost": "<b>サーバーとの接続が切断しました</b><br>再接続するまで閲覧モードになります。",
"button_newsheet": "新規スプレッドシート",
"button_newkanban": "新規カンバン",
"button_newkanban": "新規カンバン",
"button_newwhiteboard": "新規ホワイトボード",
"button_newslide": "新規プレゼンテーション",
"button_newpoll": "新規投票・アンケート",
@ -67,7 +67,7 @@
"creation_owners": "オーナー",
"download_mt_button": "ダウンロード",
"fc_rename": "名前を変更",
"forgotten": "ごみ箱へ移動",
"forgotten": "ごみ箱へ移動しました",
"filePicker_close": "閉じる",
"upload_size": "容量",
"propertiesButton": "プロパティ",
@ -111,7 +111,7 @@
"settings_backupCategory": "バックアップ",
"settings_backup": "バックアップ",
"settings_title": "設定",
"settings_cat_subscription": "サブスクリプション",
"settings_cat_subscription": "定額利用",
"settings_cat_drive": "CryptDrive",
"settings_cat_account": "アカウント",
"settings_save": "保存",
@ -125,7 +125,7 @@
"login_invalUser": "ユーザー名を入力してください",
"register_importRecent": "匿名セッションのドキュメントをインポート",
"importButton": "インポート",
"main_catch_phrase": "コラボレーションスイート<br>暗号化されかつオープンソース",
"main_catch_phrase": "コラボレーションスイート<br>端末間暗号化とオープンソース",
"tos_3rdparties": "私たちは、法令に基づく場合を除き、個人情報を第三者に提供しません。",
"tos_logs": "あなたのブラウザからサーバーに送信されたメタデータは、サービスを維持するために記録される場合があります。",
"tos_availability": "私たちはこのサービスがあなたの役に立つことを願っていますが、可用性や性能は保証できません。定期的にデータをエクスポートしてください。",
@ -150,7 +150,7 @@
"logoutButton": "ログアウト",
"login_login": "ログイン",
"autostore_hide": "保存しない",
"autostore_store": "保存する",
"autostore_store": "保存",
"autostore_notstored": "この{0}はあなたのCryptDriveに保存されていません。今すぐ保存しますか",
"user_displayName": "表示名",
"exportButton": "エクスポート",
@ -166,13 +166,13 @@
"profile_upload": " 新しいアバターをアップロード",
"teams_table_generic_edit": "編集: フォルダとパッドの作成、変更、削除が可能。",
"teams_table_generic_view": "表示: フォルダとパッドへのアクセス(閲覧のみ)。",
"teams_table_generic_own": "チームの管理: チーム名とチームのアバターの変更、オーナーの追加または削除、チームのサブスクリプションの変更、チームの削除が可能。",
"teams_table_generic_own": "チームの管理: チーム名とチームのアバターの変更、オーナーの追加または削除、チームの定額利用に関する変更、チームの削除が可能。",
"teams_table_owners": "チームの管理",
"teams_table_generic_admin": "メンバーの管理: メンバーの招待および取り消し、メンバーに管理者までの権限の付与が可能。",
"teams_table_admins": "メンバーの管理",
"teams_table_generic": "権限一覧",
"teams_table": "権限",
"contacts_fetchHistory": "古い履歴を取得する",
"contacts_fetchHistory": "古い履歴を取得",
"contacts_warning": "ここに入力した全てのメッセージは永続的であり、このパッドの現在および将来の全てのユーザーが確認できます。機密情報の入力には注意してください!",
"contacts_typeHere": "ここにメッセージを入力...",
"team_cat_drive": "ドライブ",
@ -228,14 +228,14 @@
"notifications_cat_friends": "連絡先リクエスト",
"notifications_dismiss": "確認済みにする",
"settings_autostoreMaybe": "手動 (確認しない)",
"settings_autostoreNo": "手動 (常に確認する)",
"settings_autostoreNo": "手動(常に確認)",
"settings_autostoreHint": "<b>自動</b> アクセスした全てのパッドをCryptDriveに保存します。<br><b>手動(常に確認)</b> 保存していないパッドにアクセスした際、CryptDriveに保存するかどうかを確認します。<br><b>手動(確認しない)</b> アクセス先のパッドはCryptDriveに自動で保存されません。保存オプションは表示されません。",
"settings_userFeedback": "ユーザーフィードバックを有効にする",
"settings_userFeedbackHint2": "あなたのパッドのコンテンツがサーバーと共有されることはありません。",
"settings_userFeedbackHint1": "CryptPadは、ユーザーエクスペリエンスの向上のため、いくつかの非常に基本的なフィードバックを、サーバーに提供します。 ",
"settings_userFeedbackTitle": "フィードバック",
"settings_autostoreYes": "自動",
"settings_importConfirm": "このブラウザで最近使用したパッドを、あなたのユーザーアカウントのCryptDriveにインポートしますか",
"settings_importConfirm": "このブラウザで最近用したパッドを、あなたのユーザーアカウントのCryptDriveにインポートしますか",
"settings_importDone": "インポートが完了しました",
"settings_import": "インポート",
"settings_importTitle": "このブラウザでの最近のパッドをあなたのCryptDriveにインポートします",
@ -246,7 +246,7 @@
"fc_delete": "ごみ箱へ移動",
"fc_remove": "削除",
"fc_restore": "復元",
"fc_delete_owned": "完全削除",
"fc_delete_owned": "破棄",
"creation_create": "作成",
"creation_password": "パスワード\n",
"creation_expireMonths": "か月",
@ -266,7 +266,7 @@
"features_f_cryptdrive1": "CryptDriveの全機能",
"features_f_anon_note": "追加機能あり",
"features_f_anon": "匿名ユーザーの全機能",
"features_f_storage0_note": "ドキュメントは{0}日以上使用されないと削除されます",
"features_f_storage0_note": "ドキュメントは{0}日以上用されないと削除されます",
"features_f_storage0": "一時的な保存",
"features_f_cryptdrive0_note": "アクセスしたパッドをブラウザに保存して、後で開くことができます",
"features_f_cryptdrive0": "CryptDriveへの限定的なアクセス",
@ -322,7 +322,7 @@
"properties_passwordSuccessFile": "パスワードは正常に変更されました。",
"drive_sfPasswordError": "誤ったパスワードです",
"team_title": "チーム: {0}",
"password_error": "ドキュメントが存在しません!<br>このエラーは、誤ったパスワードが入力された場合、またはドキュメントがサーバーから完全削除された場合に発生します。",
"password_error": "ドキュメントが存在しません!<br>このエラーは、誤ったパスワードが入力された場合、またはドキュメントがサーバーから破棄された場合に発生します。",
"password_error_seed": "パッドが存在しません!<br>このエラーは「パスワードが追加・変更された」場合、または「パッドがサーバーから削除された」場合に発生します。",
"password_submit": "送信",
"password_placeholder": "パスワードを入力...",
@ -332,7 +332,7 @@
"properties_addPassword": "パスワードを設定",
"history_close": "閉じる",
"history_restore": "復元",
"fm_emptyTrashOwned": "ごみ箱に、あなたが所有しているドキュメントが入っています。あなたのドライブからのみ<b>削除</b>するか、全てのユーザーから<b>完全削除</b>するかを選択できます。",
"fm_emptyTrashOwned": "ごみ箱に、あなたの所有するドキュメントが入っています。あなたのドライブからのみ<b>削除</b>するか、全てのユーザーから<b>破棄</b>するかを選択できます。",
"access_destroyPad": "このドキュメントまたはフォルダを完全に削除する",
"accessButton": "アクセス",
"access_allow": "リスト",
@ -417,7 +417,7 @@
"fm_noname": "無題のドキュメント",
"fm_openParent": "フォルダに表示",
"fm_newButtonTitle": "新しいドキュメントやフォルダを作成したり、ファイルを現在のフォルダにインポートしたりできます。",
"contacts_info4": "チャットの参加者のどちらも履歴を削除できます",
"contacts_info4": "チャットの参加者は誰でも履歴を消去できます",
"contacts_info2": "連絡先のアイコンをクリックしてチャットを開始",
"contacts_confirmRemove": "<em>{0}</em>をあなたの連絡先から削除してよろしいですか?",
"profile_error": "プロフィールの作成時にエラーが発生しました: {0}",
@ -475,7 +475,7 @@
"poll_create_option": "新しいオプションを追加",
"poll_create_user": "新しいユーザーを追加",
"pad_mediatagImport": "あなたのCryptDriveに保存",
"admin_listMyInstanceLabel": "このインスタンスをリストに表示する",
"admin_listMyInstanceLabel": "このインスタンスをリストに表示",
"admin_checkupTitle": "インスタンスの設定を検証",
"cba_disable": "消去して無効にする",
"upload_pending": "保留中",
@ -595,7 +595,7 @@
"toolbar_file": "ファイル",
"drive_treeButton": "ファイル",
"toolbar_insert": "挿入",
"fm_sort": "並び替え",
"fm_sort": "並び替え",
"comments_comment": "コメント",
"comments_resolve": "解決",
"comments_reply": "返信",
@ -765,25 +765,25 @@
"errorState": "重大なエラー: {0}",
"realtime_unrecoverableError": "回復不能なエラーが発生しました。OKをクリックして再読み込みを行ってください。",
"disabledApp": "このアプリケーションは無効になっています。詳細については、このCryptPadの管理者にお問い合わせください。",
"deletedFromServer": "パッドは完全削除されました",
"deletedFromServer": "ドキュメントが破棄されました",
"newVersionError": "新しいバージョンのCryptPadがあります。<br><a href='#'>リロードする</a>と新しいバージョンを読み込みます。<em>Esc</em>キーを押すと<b>オフラインモード</b>でコンテンツにアクセスします。",
"errorRedirectToHome": "<em>Esc</em>キーを押すとCryptDriveにリダイレクトします。",
"errorCopy": " <em>Esc</em>キーを押すと、閲覧モードで引き続きコンテンツにアクセスできます。",
"invalidHashError": "要求したドキュメントの URL が無効です。",
"invalidHashError": "要求したドキュメントのURLが無効です。",
"chainpadError": "コンテンツを更新する際に重大なエラーが発生しました。コンテンツが失われないよう、閲覧モードで表示されています。<br>このパッドを表示し続けるには<em>Esc</em>キーを押し、再度編集を試みるにはリロードをしてください。",
"inactiveError": "このパッドは使用されていなかったため削除されました。Escキーを押して新しいパッドを作成します。",
"deletedError": "このパッドは所有者によって削除されたため、使用できなくなりました。",
"expiredError": "このパッドは使用期限が過ぎてしまったため、使用できなくなりました。",
"inactiveError": "このパッドは利用されていなかったため削除されました。Escキーを押すと新しいパッドを作成します。",
"deletedError": "このドキュメントは削除されたため、利用できなくなりました。",
"expiredError": "このパッドは利用期限を過ぎてしまったため、利用できなくなりました。",
"anonymousStoreDisabled": "このCryptPadのインスタンスの管理者は、匿名ユーザーによる保存を無効に設定しています。CryptDriveを使用するにはログインする必要があります。",
"padNotPinnedVariable": "このパッドは{4}日使用しないと期限切れになります。{0}ログイン{1}または{2}登録{3}し保存してください。",
"padNotPinned": "このパッドは3ヶ月間使用しないと有効期限が切れます。{0}ログイン{1}するか{2}登録{3}して保存してください。",
"padNotPinnedVariable": "このパッドは{4}日間利用しないと有効期限が切れます。{0}ログイン{1}するか{2}登録{3}して保存してください。",
"padNotPinned": "このパッドは3か月間利用しないと有効期限が切れます。{0}ログイン{1}するか{2}登録{3}して保存してください。",
"onLogout": "ログアウトしました。{0}ここをクリック{1}するか<br><em>Escape</em>キーを押すと、閲覧モードでパッドにアクセスできます。",
"typeError": "このパッドは選択したアプリケーションと互換性がありません",
"form_type_page": "ページ分割",
"form_description_default": "ここにテキストを入力",
"team_pcsSelectHelp": "所有するパッドをチームのドライブに作成すると、そのパッドのオーナー権はチームに与えられます。",
"sharedFolders_create_owned": "フォルダを所有する",
"creation_owned1": "<b>所有している</b>項目は、オーナーの望むときにいつでも完全削除できます。完全削除すると、他のユーザーのCryptDriveからも削除されます。",
"sharedFolders_create_owned": "所有するフォルダ",
"creation_owned1": "<b>所有している</b>項目は、オーナーの望むときにいつでも破棄できます。破棄すると、他のユーザーのCryptDriveからも削除されます。",
"creation_owned": "パッドを所有",
"uploadFolder_modal_owner": "所有するファイル",
"upload_modal_owner": "所有するファイル",
@ -824,7 +824,7 @@
"pad_goToAnchor": "アンカーに移動",
"oo_cantMigrate": "この表はアップロードの最大のサイズを超えているため、移行することができません。",
"footer_roadmap": "ロードマップ",
"settings_deleteSubscription": "サブスクリプションを管理",
"settings_deleteSubscription": "定額利用を管理",
"broadcast_translations": "翻訳",
"admin_broadcastCancel": "メッセージを削除",
"admin_broadcastButton": "送信",
@ -863,7 +863,7 @@
"broadcast_end": "終了",
"broadcast_start": "開始",
"broadcast_preview": "通知をプレビュー",
"team_inviteLinkError": "リンクの作成にエラーが発生しました。",
"team_inviteLinkError": "リンクの作成にエラーが発生しました。",
"team_inviteLinkSetPassword": "リンクをパスワードで保護(推奨)",
"team_inviteLinkNote": "プライベート・メッセージを追加",
"contacts_muteInfo": "ミュートしたユーザーからは通知を受け取りません。<br>ミュートしたことは相手に通知されません。 ",
@ -1252,7 +1252,7 @@
"owner_removeMeConfirm": "オーナー権を放棄しようとしています。これは取り消せません。よろしいですか?",
"requestEdit_confirm": "{1}がパッド「<b>{0}</b>」の編集権を要求しました。編集権を与えますか?",
"admin_supportInitHelp": "サーバーはサポートメールボックスを使用するように設定されていません。サポートメールボックスを有効にし、ユーザーからメッセージを受け取るためには、サーバーの管理者に連絡し、「./scripts/generate-admin-keys.js」のスクリプトを実行してもらい、生成された公開鍵を「config.js」に保存して、秘密鍵をあなたに送信してもらうよう依頼する必要があります。",
"feedback_privacy": "私たちはプライバシー配慮すると同時に、CryptPadを使いやすくしたいと望んでいます。このファイルは、実行されたアクションを特定するパラメーターと共に要求され、ユーザーにとって重要なUI機能を特定するために使用されます。",
"feedback_privacy": "私たちはプライバシー配慮すると同時に、CryptPadを使いやすくしたいと望んでいます。このファイルは、実行されたアクションを特定するパラメーターと共に要求され、ユーザーにとって重要なUI機能を特定するために使用されます。",
"register_warning_note": "暗号化を行うCryptPadの性質上、サービス管理者は、ユーザー名とパスワードを忘れた場合にデータを回復することができません。ユーザー名とパスワードを安全な場所に保管してください。",
"history_restoreDriveTitle": "選択したバージョンのCryptDriveを復元",
"errorPopupBlocked": "新しいタブを開く許可が必要です。お使いのブラウザのアドレスバーから、ポップアップウィンドウを許可してください。これらのウィンドウが広告の表示に使用されることはありません。",
@ -1308,8 +1308,8 @@
"share_linkPasswordAlert": "この項目はパスワードで保護されています。リンクを受け取った相手はパスワードを入力する必要があります。",
"register_notes_title": "重要な注意事項",
"teams_table_specificHint": "以前のバージョンの共有フォルダでは、閲覧者は既存のパッドを変更することができます。 これらのフォルダで作成またはコピーしたパッドには、標準の権限が与えられます。",
"broadcast_maintenance": "<b>{0}</b>から<b>{1}</b>の間でメンテナンスを予定しています。その間CryptPadは使用できません。",
"admin_archiveHint": "ドキュメントを完全削除することなく、利用できないよう設定できます。「アーカイブ」フォルダに移動し、数日後に削除します(期間については設定ファイルより設定できます)。",
"broadcast_maintenance": "<b>{0}</b>から<b>{1}</b>の間でメンテナンスを予定しています。その間CryptPadは用できません。",
"admin_archiveHint": "ドキュメントを破棄することなく、利用できないよう設定できます。「アーカイブ」フォルダに移動し、数日後に削除します(期間については設定ファイルより設定できます)。",
"admin_unarchiveHint": "アーカイブされたドキュメントを復元できます",
"admin_registrationTitle": "登録を締め切る",
"admin_defaultlimitHint": "ユーザー定義のルールが適用されていない際の最大のストレージ容量(ユーザーとチームについて)を設定できます",
@ -1368,5 +1368,15 @@
"reminder_time": "<b>{0}</b>が今日の{1}にあります",
"form_answerWarning": "本人であることが確認されていません",
"team_leaveOwner": "チームから退出する前に、オーナーの役割から降格してください。チームには最低1人以上のオーナーが必要です。あなたが唯一のオーナーの場合は、別のオーナーを追加してください。",
"form_exportCSV": "CSVにエクスポート"
"form_exportCSV": "CSVにエクスポート",
"fm_link_new": "新しいリンク",
"notification_openLink": "{1}からリンク「 <b>{0}</b>」を受け取りました:",
"fm_link_type": "リンク",
"fm_link_url": "URL",
"fm_link_name": "リンク名",
"form_anonName": "あなたの名前",
"notification_linkShared": "{0}があなたとリンクを共有しました: <b>{1}</b>",
"fm_link_name_placeholder": "あなたのリンク",
"fm_link_warning": "注意URLが200字を超えています",
"fm_link_invalid": "URLが無効です"
}

View File

@ -1278,7 +1278,7 @@
"form_submit": "Submit",
"form_update": "Update",
"form_reset": "Reset",
"form_sent": "Sent",
"form_sent": "Your response was submitted",
"form_delete": "Delete",
"form_submitWarning": "Submit anyway",
"form_updateWarning": "Update anyway",
@ -1368,5 +1368,16 @@
"admin_purpose_business": "For a business or commercial organization",
"admin_instancePurposeHint": "Why do you run this instance? Your answer will be used to inform the development roadmap if your telemetry is enabled.",
"team_leaveOwner": "Please demote yourself from the owner role before leaving the team. Note that teams must have at least one owner, please add one before proceeding if you are currently the only owner.",
"form_exportCSV": "Export to CSV"
"form_exportCSV": "Export to CSV",
"notification_openLink": "You've received a link <b>{0}</b> from {1}:",
"fm_link_new": "New Link",
"fm_link_type": "Link",
"fm_link_name": "Link name",
"fm_link_url": "URL",
"fm_link_name_placeholder": "My link",
"notification_linkShared": "{0} has shared a link with you: <b>{1}</b>",
"form_anonName": "Your name",
"form_answerAs": "Answer as",
"fm_link_warning": "Warning: the URL exceeds 200 characters",
"fm_link_invalid": "Invalid URL"
}

View File

@ -0,0 +1,208 @@
{
"backgroundButtonTitle": "Pakeiskite pristatymo fono spalvą",
"presentButtonTitle": "Įeikite į pristatymo režimą",
"previewButtonTitle": "Rodyti arba slėpti „Markdown“ peržiūros režimą",
"template_empty": "Šablono nėra",
"template_import": "Importuoti šabloną",
"useTemplateCancel": "Pradėk šviežiai (Esc)",
"useTemplateOK": "Pasirinkite šabloną (Enter)",
"useTemplate": "Pradėti nuo šablono?",
"selectTemplate": "Pasirinkite šabloną arba paspauskite „escape“",
"templateSaved": "Šablonas išsaugotas!",
"saveTemplatePrompt": "Pasirinkite šablono pavadinimą",
"saveTemplateButton": "Išsaugoti kaip šabloną",
"uploadButtonTitle": "Įkelkite naują failą į savo „CryptDrive“",
"uploadFolderButton": "Įkelti aplanką",
"uploadButton": "Įkelti failus",
"newButtonTitle": "Sukurti naują padą",
"newButton": "Naujas",
"userAccountButton": "Tavo paskyra",
"chatButton": "Čiatas",
"userListButton": "Vartotojų sąrašas",
"shareSuccess": "Nukopijuota nuoroda",
"shareButton": "Dalintis",
"movedToTrash": "Šis apdas buvo perkeltas į šiukšliadėžę. <br> <a> Pasiekite mano diską </a>",
"forgetPrompt": "Spustelėjus Gerai, ši trinkelė bus perkelta į šiukšliadėžę. Ar tu tuo tikras?",
"forgetButton": "Ištrinti",
"saveTitle": "Išsaugoti pavadinimą (enter)",
"clickToEdit": "Spauskite redaguoti",
"user_accountName": "Paskyros vardas",
"user_displayName": "Rodomas pavadinimas",
"user_rename": "Keisti rodomą pavadinimą",
"changeNamePrompt": "Pakeiskite savo vardą (palikite tuščią, kad būtų anoniminis): ",
"exportPrompt": "Kaip norėtumėte pavadinti savo failą?",
"exportButtonTitle": "Eksportuokite padą į vietinį failą",
"exportButton": "Eksportuoti",
"importButton": "Importuoti",
"importButtonTitle": "Importuokite padą iš vietinio failo",
"pinLimitDrive": "Pasiekėte saugyklos limitą. <br> Negalite sukurti naujų padų.",
"pinLimitNotPinned": "Pasiekėte saugyklos limitą. <br> Šis padas nėra saugomas jūsų „CryptDrive“.",
"pinLimitReachedAlertNoAccounts": "Pasiekėte saugyklos limitą",
"pinLimitReachedAlert": "Pasiekėte saugyklos limitą. Nauji padai nebus saugomi jūsų „CryptDrive“. <br> Norėdami padidinti savo limitą, galite pašalinti padus iš savo „CryptDrive“ arba <a> užsiprenumeruoti </a>premium sąskaitą.",
"pinLimitReached": "Pasiekėte saugyklos limitą",
"formattedKB": "{0} KB",
"formattedGB": "{0} GB",
"formattedMB": "{0} MB",
"KB": "KB",
"GB": "GB",
"MB": "MB",
"storageStatus": "Saugykla: <br /> <b> {0} </b> sunaudota iš <b> {1} </b>",
"upgrade": "Atnaujinti",
"upgradeAccount": "Atnaujinti paskyrą",
"language": "Kalba",
"userlist_offline": "Šiuo metu esate neprisijungę, vartotojų sąrašas nepasiekiamas.",
"editor": "redaktorius",
"viewers": "žiūrovai",
"viewer": "žiūrovas",
"users": "Vartotojai",
"anonymous": "Anoniminis",
"readonly": "Tik skaityti",
"errorState": "Kritinė klaida: {0}",
"forgotten": "Perkeltas į šiukšliadėžę",
"initializing": "Inicijuojama ...",
"typing": "Redaguojama",
"reconnecting": "Jungiamasi iš naujo",
"synchronizing": "Sinchronizuojama",
"disconnected": "Atjungta",
"realtime_unrecoverableError": "Įvyko neatkuriama klaida. Norėdami perkrauti, spustelėkite Gerai.",
"disabledApp": "Ši programa buvo išjungta. Norėdami gauti daugiau informacijos, susisiekite su „CryptPad“ administratoriumi.",
"mustLogin": "Norėdami patekti į šį puslapį, turite būti prisijungę",
"deletedFromServer": "Dokumentas ištrintas",
"deleted": "Ištrinta",
"saved": "Užsaugota",
"error": "Klaida",
"loading": "Kraunasi...",
"newVersionError": "Yra nauja „CryptPad“ versija. <br> <a href='#'> Perkraukite iš naujo </a>, jei norite naudoti naują versiją, arba paspauskite „Escape“, kad pasiektumėte savo turinį <b> offline režimu </b>.",
"errorRedirectToHome": "Paspauskite <em> Esc </em>, kad būtumėte nukreipti į „CryptDrive“.",
"errorCopy": " Vis dar galite naudoti dabartinę versiją tik skaitymo režimu paspausdami <em> Esc </em>.",
"invalidHashError": "Prašytame dokumente yra neteisingas URL.",
"chainpadError": "Atnaujinant turinį įvyko kritinė klaida. Šis puslapis veikia tik skaitymo režimu, kad neprarastumėte savo darbo. <br> Jei norite toliau peržiūrėti šį padą, paspauskite <em> Esc </em> arba įkelkite iš naujo, jei norite bandyti redaguoti dar kartą.",
"inactiveError": "Šis padas buvo ištrintas dėl neveiklumo. Paspauskite Esc, kad sukurtumėte naują padą.",
"deletedError": "Šis dokumentas ištrintas ir jo nebėra.",
"expiredError": "Šis Padas nebegalioja ir yra ištrintas.",
"anonymousStoreDisabled": "Šios instancijos nepalaiko anoniminio vartojimo. Jūs turite prisiregistruoti, kad galėtumete naudoti CryptDrive.",
"padNotPinnedVariable": "Šis padas nustos galioti po {4} neaktyvių dienų, {0}prisijungti{1} arba {2}registruotis{3} kad užsaugoti.",
"padNotPinned": "Nenaudojamas padas nustos galioti po 3mėn, {0}prisijungti{1} arba {2} registruotis{3} kad užsaugoti.",
"onLogout": "Jūs esate prisijungęs, {0}Spausti čia{1}Prisjungti čia<br>arba spausti <em>Escape</em> pasiekti savo pad tik skaityti.",
"typeError": "Šis Pad nesuderinama su pasirinkta programa",
"common_connectionLost": "<b> serverio sujungimas prarastas<b><br> Tik skaitymo rėžimas kol sujungimas atsiras.",
"button_newsheet": "Naujas Lapas",
"button_newkanban": "Naujas kanbanas",
"button_newwhiteboard": "Nauja Lenta",
"button_newslide": "Nauja prezentacija",
"button_newpoll": "Nauja apklausa",
"button_newcode": "Naujas Kodas",
"button_newpad": "Naujas Tekstas",
"type": {
"form": "Forma",
"teams": "Komandos",
"sheet": "Lapas",
"contacts": "Kontaktai",
"todo": "Todo",
"media": "Medija",
"file": "Failas",
"whiteboard": "Lenta",
"drive": "CryptDiskas",
"slide": "Prezentacija",
"kanban": "Kanbanas",
"poll": "Apklausa",
"code": "Kodas",
"pad": "Tekstas"
},
"main_title": "CryptPad: lengvai valdomas, bendradarbiavimas realiuoju laiku",
"filePicker_close": "Uždaryti",
"filePickerButton": "Įterpkite failą, saugomą „CryptDrive“",
"printBackgroundRemove": "Pašalinkite šį foną",
"printBackgroundNoValue": "<em> Foninis vaizdas nerodomas </em>",
"printBackgroundValue": "<b> Dabartinis darbalaukis: </b> <em> {0} </em>",
"printBackgroundButton": "Pasirinkti paveiksliuką",
"printBackground": "Naudokite fono vaizdą",
"printTransition": "Įgalinti perėjimo animacijas",
"printCSS": "Stiliaus taisyklės (CSS):",
"printTitle": "Parodykite pado pavadinimą",
"printDate": "Rodyti datą",
"printSlideNumber": "Rodyti skaidrės numerį",
"printOptions": "Išdėstymo parinktys",
"printButtonTitle2": "Atspausdinkite dokumentą arba eksportuokite jį kaip PDF failą",
"printButton": "Atspausdinti (neter)",
"printText": "Atspausdinti",
"propertiesButtonTitle": "Gaukite pado savybes",
"propertiesButton": "Savybės",
"colorButtonTitle": "Pakeiskite teksto spalvą prezentacijos režime",
"poll_create_user": "Pridėti naują vartotoją",
"poll_publish_button": "Publikuoti",
"kanban_addBoard": "Pridėkite lentą",
"kanban_working": "Atliekama",
"kanban_done": "Padaryta",
"kanban_todo": "Atlikti",
"kanban_item": "Elementas {0}",
"kanban_newBoard": "Nauja lenta",
"pad_mediatagOptions": "Vaizdo ypatybės",
"pad_mediatagImport": "Išsaugokite savo „CryptDrive“",
"pad_mediatagPreview": "Peržiūra",
"pad_mediatagBorder": "Kraštinės plotis (px)",
"pad_mediatagRatio": "Išlaikyti santykį",
"pad_mediatagHeight": "Aukštis (px)",
"pad_mediatagWidth": "Plotis (px)",
"pad_mediatagTitle": "„Media-Tag“ nustatymai",
"openLinkInNewTab": "Atidarykite nuorodą naujame skirtuke",
"history_restoreDone": "Dokumentas atkurtas",
"history_restorePrompt": "Ar tikrai norite pakeisti dabartinę dokumento versiją į rodoma versiją?",
"history_restoreTitle": "Atkurkite pasirinktą dokumento versiją",
"history_closeTitle": "Uždarykite istoriją",
"history_loadMore": "Įkelti daugiau istorijos",
"history_prev": "Ankstesnė versija",
"history_next": "Kita versija",
"historyButton": "Rodyti dokumentų istoriją",
"historyText": "Istorija",
"help_button": "Pagalba",
"show_help_button": "Rodyti pagalbą",
"cancelButton": "Baigti (esc)",
"cancel": "Baigti",
"okButton": "Taip (enter)",
"ok": "Taip",
"notifyLeft": "{0} išėjo iš bendradarbiavimo sesijos",
"notifyRenamed": "{0} dabar žinomas kaip {1}",
"notifyJoined": "{0} prisijungė prie bendradarbiavimo sesijos",
"fileEmbedTag": "Tada įdėkite šią medijos žymą visur, kur norite įdėti:",
"fileEmbedScript": "Norėdami įterpti šį failą, vieną kartą įtraukite šį scenarijų į savo puslapį, kad įkeltumėte medijos žymą:",
"viewEmbedTag": "Norėdami įterpti šį įklotą, įtraukite šį „iframe“ į savo puslapį visur, kur norite. Galite jį stilizuoti naudodami CSS arba HTML atributus.",
"viewShare": "Tik skaityti nuoroda",
"editShare": "Redaguojama nuoroda",
"themeButtonTitle": "Pasirinkite spalvų dizainą, kurią naudosite kodų ir skaidrių redaktoriams",
"themeButton": "Dizainas",
"languageButtonTitle": "Pasirinkite sintaksės paryškinimui naudojamą kalbą",
"languageButton": "Kalba",
"slide_invalidLess": "Netinkamas pasirinktinis stilius",
"slideOptionsTitle": "Tinkinkite skaidres",
"slideOptionsText": "Pasirinkimai",
"tags_noentry": "Negalite pažymėti ištrinto pado!",
"tags_duplicate": "Pasikartojanti žyma: {0}",
"tags_notShared": "Jūsų žymos nebendrinamos su kitais vartotojais",
"tags_add": "Atnaujinkite pažymėtų padų žymas",
"tags_title": "Žymos (tik jums)",
"filePicker_filter": "Filtruokite failus pagal pavadinimą",
"filePicker_description": "Pasirinkite failą iš „CryptDrive“, kad jį įdėtumėte arba įkeltumėte naują",
"oo_cantUpload": "Įkelti negalima, kol dalyvauja kiti vartotojai.",
"oo_reconnect": "Serverio ryšys atkurtas. Spustelėkite Gerai, jei norite iš naujo įkelti ir tęsti leidimą.",
"poll_comment_disabled": "Paskelbkite šią apklausą naudodami mygtuką ✓, kad įgalintumėte komentarus.",
"poll_comment_placeholder": "Jūsų komentaras",
"poll_comment_remove": "Ištrinti šį komentarą",
"poll_comment_submit": "Siųsti",
"poll_comment_add": "Pridėti komentarą",
"poll_comment_list": "Komentarai",
"poll_total": "Bendras",
"poll_bookmarked_col": "Tai yra jūsų pažymėtas stulpelis. Jums visada bus atrakinta ir rodoma pradžioje.",
"poll_bookmark_col": "Pažymėkite šį stulpelį taip, kad jis visada būtų atrakintas ir rodomas pradžioje",
"poll_unlocked": "Atrakinta",
"poll_locked": "Užrakinta",
"poll_edit": "Redaguoti",
"poll_remove": "Pašalinti",
"poll_descriptionHint": "Apibūdinkite apklausą ir, kai baigsite, naudokite mygtuką ✓ (paskelbti).\nAprašymas gali būti parašytas naudojant žymėjimo sintaksę ir galite įdėti laikmenos elementus iš savo „CryptDrive“.\nVisi, turintys nuorodą, gali pakeisti aprašą, tačiau tai nerekomenduojama.",
"poll_removeUser": "Ar tikrai norite pašalinti šį vartotoją?",
"poll_removeOption": "Ar tikrai norite pašalinti šią parinktį?",
"poll_userPlaceholder": "Vardas",
"poll_optionPlaceholder": "Pasirinkimai",
"poll_commit": "Pateikti",
"poll_create_option": "Pridėti naują parinktį"
}

View File

@ -13,7 +13,8 @@
"todo": "待办事项",
"teams": "团队",
"sheet": "工作表",
"contacts": "联系我们"
"contacts": "联系我们",
"form": "从"
},
"button_newpad": "富文件檔案",
"button_newcode": "新代碼檔案",

View File

@ -17,6 +17,7 @@ define([
var SHARED_FOLDERS_TEMP = module.SHARED_FOLDERS_TEMP = "sharedFoldersTemp"; // Maybe deleted or new password
var FILES_DATA = module.FILES_DATA = Constants.storageKey;
var OLD_FILES_DATA = module.OLD_FILES_DATA = Constants.oldStorageKey;
var STATIC_DATA = module.STATIC_DATA = 'static';
// Create untitled documents when no name is given
var getLocaleDate = function () {
@ -138,6 +139,7 @@ define([
var NEW_FILE_NAME = Messages.fm_newFile || 'New file';
exp.ROOT = ROOT;
exp.STATIC_DATA = STATIC_DATA;
exp.UNSORTED = UNSORTED;
exp.TRASH = TRASH;
exp.TEMPLATE = TEMPLATE;
@ -236,6 +238,10 @@ define([
return Boolean(data.roHref && !data.href);
};
exp.isStaticFile = function (element) {
return Boolean(files[STATIC_DATA] && files[STATIC_DATA][element]);
};
var isFolder = exp.isFolder = function (element) {
if (isFolderData(element)) { return false; }
return typeof(element) === "object" || isSharedFolder(element);
@ -310,6 +316,12 @@ define([
// Get data from AllFiles (Cryptpad_RECENTPADS)
var getFileData = exp.getFileData = function (file, editable) {
if (!file) { return; }
var link = (files[STATIC_DATA] || {})[file];
if (link) {
var _link = editable ? link : Util.clone(link);
if (!editable) { _link.static = true; }
return _link;
}
var data = files[FILES_DATA][file] || {};
if (!editable) {
data = JSON.parse(JSON.stringify(data));
@ -344,6 +356,7 @@ define([
return '??';
}
var data = getFileData(file);
if (data.static) { return data.name; }
if (!file || !data || !(data.href || data.roHref)) {
error("getTitle called with a non-existing file id: ", file, data);
return;
@ -475,6 +488,11 @@ define([
});
return ret;
};
_getFiles[STATIC_DATA] = function () {
var ret = [];
if (!files[STATIC_DATA]) { return ret; }
return Object.keys(files[STATIC_DATA]).map(Number).filter(Boolean);
};
_getFiles[FILES_DATA] = function () {
var ret = [];
if (!files[FILES_DATA]) { return ret; }
@ -854,6 +872,7 @@ define([
// RENAME
exp.rename = function (path, newName, cb) {
cb = cb || function () {};
if (sframeChan) {
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "rename",
@ -891,9 +910,15 @@ define([
if (isSharedFolder(element)) {
data = files[SHARED_FOLDERS][element];
} else {
data = files[FILES_DATA][element];
data = files[FILES_DATA][element] || files[STATIC_DATA][element];
}
if (!data) { return; }
if (files[STATIC_DATA][element]) {
if (!newName || !newName.trim()) { return void cb(); }
data.name = newName;
cb();
return;
}
if (!newName || newName.trim() === "") {
delete data.filename;
if (typeof cb === "function") { cb(); }

View File

@ -192,8 +192,8 @@ define([
},
};
Messages.convertPage = "Convert"; // XXX
Messages.convert_hint = "Pick the file you want to convert. The list of output format will be visible afterward."; // XXX
Messages.convertPage = "Convert"; // XXX 4.10.0
Messages.convert_hint = "Pick the file you want to convert. The list of output format will be visible afterward."; // XXX 4.10.0
var createToolbar = function () {
var displayed = ['useradmin', 'newpad', 'limit', 'pageTitle', 'notifications'];

View File

@ -247,6 +247,15 @@
.cp-form-anon-answer {
text-align: center;
margin: 20px 0 30px 0;
.cp-form-anon-answer-input {
margin-top: 20px;
display: flex;
white-space: nowrap;
align-items: center;
input {
margin-left: 10px;
}
}
}
}
@ -464,6 +473,16 @@
display: flex;
flex-flow: column;
position: relative;
#cp-form-response-msg {
background: @cp_form-bg1;
margin-bottom: 20px;
padding: 10px;
p:last-child {
margin-bottom: 0;
}
}
.cp-form-creator-results-controls {
margin-bottom: 20px;
//background: @cp_form-bg1;
@ -529,6 +548,7 @@
.cp-form-individual {
background: @cp_form-bg1;
padding: 10px;
margin-bottom: 20px;
& > *:not(:last-child) {
margin-right: 10px;
}
@ -541,6 +561,9 @@
margin-right: 5px;
}
}
a, a:visited {
color: @cryptpad_color_link;
}
}
}
}
@ -659,6 +682,16 @@
.avatar_main(30px);
margin-right: 10px;
}
&.cp-clickable {
cursor: pointer;
&:hover {
color: @cryptpad_color_link;
&::after {
font-family: FontAwesome;
content: "\00a0\f06e";
}
}
}
}
.cp-poll-time-day {
flex-basis: 100px;
@ -677,6 +710,16 @@
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.cp-form-poll-option, .cp-poll-time-day {
flex-flow: column;
text-align: center;
.cp-form-weekday-separator {
display: none;
}
}
.cp-poll-time-day {
height: 50px;
}
}
&.cp-form-poll-switch {
display: flex;
@ -706,12 +749,21 @@
}
.cp-form-poll-option, .cp-poll-switch {
width: 200px;
.cp-form-weekday-separator {
margin-right: 5px;
margin-left: 5px;
}
}
.cp-poll-time-day {
flex-basis: 40px;
border-right: none;
border-right: 1px solid @cryptpad_text_col;
border-bottom: 0px;
flex-flow: column;
text-align: center;
.cp-form-weekday-separator {
display: none;
}
}
}
.cp-form-poll-choice, .cp-form-poll-answer {

View File

@ -68,13 +68,9 @@ define([
var APP = window.APP = {
};
var is24h = false;
var is24h = UIElements.is24h();
var dateFormat = "Y-m-d H:i";
var timeFormat = "H:i";
try {
is24h = !new Intl.DateTimeFormat(navigator.language, { hour: 'numeric' }).format(0).match(/AM/);
} catch (e) {}
is24h = false;
if (!is24h) {
dateFormat = "Y-m-d h:i K";
timeFormat = "h:i K";
@ -298,6 +294,7 @@ define([
del
]);
$(del).click(function () {
var $block = $(el).closest('.cp-form-edit-block');
$(el).remove();
// We've just deleted an item/option so we should be under the MAX limit and
// we can show the "add" button again
@ -306,6 +303,13 @@ define([
$add.show();
if (v.type === "time") { $(addMultiple).show(); }
}
// decrement the max choices input when there are fewer options than the current maximum
if (maxInput) {
var inputs = $block.find('input').length;
var $maxInput = $(maxInput);
var currentMax = Number($maxInput.val());
$maxInput.val(Math.min(inputs, currentMax));
}
});
return el;
};
@ -575,7 +579,22 @@ define([
];
};
var makePollTable = function (answers, opts) {
var getWeekDays = function (large) {
var baseDate = new Date(2017, 0, 1); // just a Sunday
var weekDays = [];
for(var i = 0; i < 7; i++) {
weekDays.push(baseDate.toLocaleDateString(undefined, { weekday: 'long' }));
baseDate.setDate(baseDate.getDate() + 1);
}
if (!large) {
weekDays = weekDays.map(function (day) { return day.slice(0,3); });
}
return weekDays.map(function (day) { return day.replace(/^./, function (str) { return str.toUpperCase(); }); });
};
// "resultsPageObj" is an object with "content" and "answers"
// only available when viewing the Responses page
var makePollTable = function (answers, opts, resultsPageObj) {
// Sort date values
if (opts.type !== "text") {
opts.values.sort(function (a, b) {
@ -583,18 +602,25 @@ define([
});
}
// Create first line with options
var allDays = getWeekDays(true);
var els = opts.values.map(function (data) {
var _date;
if (opts.type === "day") {
var _date = new Date(data);
_date = new Date(data);
data = _date.toLocaleDateString();
}
if (opts.type === "time") {
var _dateT = new Date(data);
data = Flatpickr.formatDate(_dateT, timeFormat);
_date = new Date(data);
data = Flatpickr.formatDate(_date, timeFormat);
}
var day = _date && allDays[_date.getDay()];
return h('div.cp-poll-cell.cp-form-poll-option', {
title: Util.fixHTML(data)
}, data);
}, [
opts.type === 'day' ? h('span.cp-form-weekday', day) : undefined,
opts.type === 'day' ? h('span.cp-form-weekday-separator', ' - ') : undefined,
h('span', data)
]);
});
// Insert axis switch button
var switchAxis = h('button.btn.btn-default', [
@ -611,13 +637,20 @@ define([
opts.values.forEach(function (d) {
var date = new Date(d);
var day = date.toLocaleDateString();
_days[day] = _days[day] || 0;
_days[day]++;
_days[day] = {
n: (_days[day] && _days[day].n) || 0,
name: allDays[date.getDay()]
};
_days[day].n++;
});
Object.keys(_days).forEach(function (day) {
days.push(h('div.cp-poll-cell.cp-poll-time-day', {
style: 'flex-grow:'+(_days[day]-1)+';'
}, day));
style: 'flex-grow:'+(_days[day].n - 1)+';'
}, [
h('span.cp-form-weekday', _days[day].name),
h('span.cp-form-weekday-separator', ' - '),
h('span', day)
]));
});
lines.unshift(h('div', days));
}
@ -640,13 +673,19 @@ define([
}, v);
return cell;
});
els.unshift(h('div.cp-poll-cell.cp-poll-answer-name', {
var nameCell;
els.unshift(nameCell = h('div.cp-poll-cell.cp-poll-answer-name', {
title: Util.fixHTML(name)
}, [
avatar,
h('span', name)
]));
bodyEls.push(h('div', els));
if (resultsPageObj && (APP.isEditor || APP.isAuditor)) {
$(nameCell).addClass('cp-clickable').click(function () {
APP.renderResults(resultsPageObj.content, resultsPageObj.answers, answerObj.curve);
});
}
});
}
var body = h('div.cp-form-poll-body', bodyEls);
@ -788,6 +827,7 @@ define([
if (filterCurve && user === filterCurve) { return; }
try {
return {
curve: user,
user: answers[user].msg._userdata,
results: answers[user].msg[uid]
};
@ -950,7 +990,7 @@ define([
printResults: function (answers, uid) {
var results = [];
var empty = 0;
Object.keys(answers).forEach(function (author) {
Object.keys(answers).forEach(function (author) { // TODO deduplicate these?
var obj = answers[author];
var answer = obj.msg[uid];
if (!answer || !answer.trim()) { return empty++; }
@ -1016,7 +1056,7 @@ define([
printResults: function (answers, uid) {
var results = [];
var empty = 0;
Object.keys(answers).forEach(function (author) {
Object.keys(answers).forEach(function (author) { // TODO deduplicate these
var obj = answers[author];
var answer = obj.msg[uid];
if (!answer || !answer.trim()) { return empty++; }
@ -1090,8 +1130,7 @@ define([
var obj = answers[author];
var answer = obj.msg[uid];
if (!answer || !answer.trim()) { return empty++; }
count[answer] = count[answer] || 0;
count[answer]++;
Util.inc(count, answer);
});
Object.keys(count).forEach(function (value) {
results.push(h('div.cp-form-results-type-radio-data', [
@ -1193,8 +1232,7 @@ define([
var c = count[q_uid] = count[q_uid] || {};
var res = answer[q_uid];
if (!res || !res.trim()) { return; }
c[res] = c[res] || 0;
c[res]++;
Util.inc(c, res);
});
});
Object.keys(count).forEach(function (q_uid) {
@ -1304,8 +1342,7 @@ define([
var answer = obj.msg[uid];
if (!Array.isArray(answer) || !answer.length) { return empty++; }
answer.forEach(function (val) {
count[val] = count[val] || 0;
count[val]++;
Util.inc(count, val);
});
});
Object.keys(count).forEach(function (value) {
@ -1420,8 +1457,7 @@ define([
var res = answer[q_uid];
if (!Array.isArray(res) || !res.length) { return; }
res.forEach(function (v) {
c[v] = c[v] || 0;
c[v]++;
Util.inc(c, v);
});
});
});
@ -1470,7 +1506,9 @@ define([
if (!Array.isArray(opts.values)) { return; }
var map = {};
var invMap = {};
var els = opts.values.map(function (data, i) {
var sorted = false;
Util.shuffleArray(opts.values);
var els = opts.values.map(function (data) {
var uid = Util.uid();
map[uid] = data;
invMap[data] = uid;
@ -1479,7 +1517,7 @@ define([
h('i.fa.fa-ellipsis-v'),
h('i.fa.fa-ellipsis-v'),
]),
h('span.cp-form-sort-order', (i+1)),
h('span.cp-form-sort-order', '?'),
h('span', data)
]);
$(div).data('val', data);
@ -1490,10 +1528,11 @@ define([
els
]);
var $tag = $(tag);
var reorder = function () {
var reorder = function (reset) {
$tag.find('.cp-form-type-sort').each(function (i, el) {
$(el).find('.cp-form-sort-order').text(i+1);
$(el).find('.cp-form-sort-order').text(reset ? '?' : i+1);
});
sorted = !reset;
};
var cursorGetter;
var setCursorGetter = function (f) { cursorGetter = f; };
@ -1516,16 +1555,18 @@ define([
return {
tag: tag,
getValue: function () {
if (!sorted) { return; }
return sortable.toArray().map(function (id) {
return map[id];
});
},
reset: function () {
Util.shuffleArray(opts.values);
var toSort = (opts.values).map(function (val) {
return invMap[val];
});
sortable.sort(toSort);
reorder();
reorder(true);
},
edit: function (cb, tmp) {
var v = Util.clone(opts);
@ -1554,7 +1595,7 @@ define([
if (!Array.isArray(answer) || !answer.length) { return empty++; }
answer.forEach(function (el, i) {
var score = l - i;
count[el] = (count[el] || 0) + score;
Util.inc(count, el, score);
});
});
var sorted = Object.keys(count).sort(function (a, b) {
@ -1583,7 +1624,7 @@ define([
if (!opts) { opts = TYPES.poll.defaultOpts; }
if (!Array.isArray(opts.values)) { return; }
var lines = makePollTable(answers, opts);
var lines = makePollTable(answers, opts, false);
// Add form
var addLine = opts.values.map(function (data) {
@ -1667,31 +1708,53 @@ define([
};
},
printResults: function (answers, uid, form) {
printResults: function (answers, uid, form, content) {
var opts = form[uid].opts || TYPES.poll.defaultOpts;
var _answers = getBlockAnswers(answers, uid);
var lines = makePollTable(_answers, opts);
// If content is defined, we'll be able to click on a row to display
// all the answers of this user
var lines = makePollTable(_answers, opts, content && {
content: content,
answers: answers
});
var total = makePollTotal(_answers, opts);
if (total) { lines.push(h('div', total)); }
return h('div.cp-form-type-poll', lines);
},
exportCSV: function (answer) {
if (answer === false) { return; }
if (!answer || !answer.values) { return ['']; }
exportCSV: function (answer, form) {
var opts = form.opts || TYPES.poll.defaultOpts;
var q = form.q || Messages.form_default;
if (answer === false) {
var cols = opts.values.map(function (key) {
return q + ' | ' + key;
});
cols.unshift(q);
return cols;
}
if (!answer || !answer.values) {
var empty = opts.values.map(function () { return ''; });
empty.unshift('');
return empty;
}
var str = '';
Object.keys(answer.values).sort().forEach(function (k, i) {
if (i !== 0) { str += ';'; }
str += k.replace(';', '').replace(':', '') + ':' + answer.values[k];
});
return [str];
var res = opts.values.map(function (key) {
return answer.values[key] || '';
});
res.unshift(str);
return res;
},
icon: h('i.cptools.cptools-form-poll')
},
};
var renderResults = function (content, answers) {
var renderResults = APP.renderResults = function (content, answers, showUser) {
var $container = $('div.cp-form-creator-results').empty();
if (!Object.keys(answers || {}).length) {
@ -1699,9 +1762,15 @@ define([
return;
}
if (content.answers.msg) {
var description = h('div.cp-form-creator-results-description#cp-form-response-msg');
var $desc = $(description).appendTo($container);
DiffMd.apply(DiffMd.render(content.answers.msg), $desc, APP.common);
}
var controls = h('div.cp-form-creator-results-controls');
var $controls = $(controls).appendTo($container);
var exportButton = h('button.btn.btn-secondary', Messages.exportButton); // XXX form_exportCSV;
var exportButton = h('button.btn.btn-secondary', Messages.form_exportCSV);
var exportCSV = h('div.cp-form-creator-results-export', exportButton);
$(exportCSV).appendTo($container);
var results = h('div.cp-form-creator-results-content');
@ -1729,7 +1798,9 @@ define([
var type = block.type;
var model = TYPES[type];
if (!model || !model.printResults) { return; }
var print = model.printResults(answers, uid, form);
// Only use content if we're not viewing individual answers
var print = model.printResults(answers, uid, form, !header && content);
var q = h('div.cp-form-block-question', block.q || Messages.form_default);
@ -1823,14 +1894,23 @@ define([
e.preventDefault();
APP.common.openURL(Hash.hashToHref(ud.profile, 'profile'));
});
if (showUser === curve) {
setTimeout(function () {
showUser = undefined;
$(viewButton).click();
});
}
return div;
});
$results.append(els);
});
if (showUser) {
$s.click();
}
};
var addResultsButton = function (framework, content) {
var $res = $(h('button.cp-toolbar-appmenu', [
var $res = $(h('button.cp-toolbar-appmenu.cp-toolbar-form-button', [
h('i.fa.fa-bar-chart'),
h('span.cp-button-name', Messages.form_results)
]));
@ -1872,25 +1952,42 @@ define([
var makeFormControls = function (framework, content, update, evOnChange) {
var loggedIn = framework._.sfCommon.isLoggedIn();
var metadataMgr = framework._.cpNfInner.metadataMgr;
var user = metadataMgr.getUserData();
if (!loggedIn && !content.answers.anonymous) { return; }
var cbox;
var anonName, $anonName;
cbox = UI.createCheckbox('cp-form-anonymous',
Messages.form_anonymousBox, true, { mark: { tabindex:1 } });
var $anonBox = $(cbox).find('input');
if (loggedIn) {
if (!content.answers.anonymous || APP.cantAnon) {
$(cbox).hide().find('input').attr('disabled', 'disabled').prop('checked', false);
}
} else {
anonName = h('div.cp-form-anon-answer-input', [
Messages.form_answerAs,
h('input', {
value: user.name || '',
placeholder: Messages.form_anonName
})
]);
$anonName = $(anonName).hide();
$anonBox.on('change', function () {
if (Util.isChecked($anonBox)) { $anonName.hide(); }
else { $anonName.show(); }
});
}
var send = h('button.cp-open.btn.btn-primary', update ? Messages.form_update : Messages.form_submit);
var reset = h('button.cp-open.btn.btn-danger-alt', Messages.form_reset);
var reset = h('button.cp-open.cp-reset-button.btn.btn-danger-alt', Messages.form_reset);
$(reset).click(function () {
if (!Array.isArray(APP.formBlocks)) { return; }
APP.formBlocks.forEach(function (data) {
if (typeof(data.reset) === "function") { data.reset(); }
});
$(reset).attr('disabled', 'disabled');
});
var $send = $(send).click(function () {
$send.attr('disabled', 'disabled');
@ -1898,14 +1995,16 @@ define([
if (!results) { return; }
var user = metadataMgr.getUserData();
if (!Util.isChecked($(cbox).find('input'))) {
if (!Util.isChecked($anonBox)) {
results._userdata = loggedIn ? {
avatar: user.avatar,
name: user.name,
notifications: user.notifications,
curvePublic: user.curvePublic,
profile: user.profile
} : { name: user.name };
} : {
name: $anonName ? $anonName.find('input').val() : user.name
};
}
var sframeChan = framework._.sfCommon.getSframeChannel();
@ -1985,7 +2084,10 @@ define([
return h('div.cp-form-send-container', [
invalid,
cbox ? h('div.cp-form-anon-answer', cbox) : undefined,
cbox ? h('div.cp-form-anon-answer', [
cbox,
anonName
]) : undefined,
reset, send
]);
};
@ -1997,6 +2099,18 @@ define([
APP.formBlocks = [];
if (APP.isClosed && content.answers.privateKey && !APP.isEditor) {
var sframeChan = framework._.sfCommon.getSframeChannel();
sframeChan.query("Q_FORM_FETCH_ANSWERS", content.answers, function (err, obj) {
var answers = obj && obj.results;
if (answers) { APP.answers = answers; }
$('body').addClass('cp-app-form-results');
$('.cp-toolbar-form-button').remove();
renderResults(content, answers);
});
return;
}
var evOnChange = Util.mkEvent();
if (!APP.isEditor) {
var _answers = Util.clone(answers || {});
@ -2004,6 +2118,7 @@ define([
delete _answers._userdata;
evOnChange.reg(function (noBeforeUnload, isSave) {
if (noBeforeUnload) { return; }
$container.find('.cp-reset-button').removeAttr('disabled');
var results = getFormResults();
if (isSave) {
answers = Util.clone(results || {});
@ -2356,6 +2471,9 @@ define([
// In view mode, add "Submit" and "reset" buttons
$container.append(makeFormControls(framework, content, Boolean(answers), evOnChange));
if (!answers) {
$container.find('.cp-reset-button').attr('disabled', 'disabled');
}
};
var getTempFields = function () {
@ -2443,6 +2561,72 @@ define([
};
refreshPublic();
var responseMsg = h('div.cp-form-response-msg-container');
var $responseMsg = $(responseMsg);
var refreshResponse = function () {
if (true) { return; } // XXX 4.10.0
$responseMsg.empty();
Messages.form_updateMsg = "Update response message"; // XXX 4.10.0
Messages.form_addMsg = "Add response message"; // XXX 4.10.0
Messages.form_responseMsg = "Add a message that will be displayed in the response page."; // XXX 4.10.0
var text = content.answers.msg ? Messages.form_updateMsg : Messages.form_addMsg;
var btn = h('button.btn.btn-secondary', text);
$(btn).click(function () {
var editor;
if (!APP.responseModal) {
var t = h('textarea');
var div = h('div', [
h('p', Messages.form_responseMsg),
t
]);
var cm = SFCodeMirror.create("gfm", CMeditor, t);
editor = APP.responseEditor = cm.editor;
editor.setOption('lineNumbers', true);
editor.setOption('lineWrapping', true);
editor.setOption('styleActiveLine', true);
editor.setOption('readOnly', false);
setTimeout(function () {
editor.setValue(content.answers.msg || '');
editor.refresh();
editor.save();
editor.focus();
});
var buttons = [{
className: 'primary',
name: Messages.settings_save,
onClick: function () {
var v = editor.getValue();
content.answers.msg = v.trim(0, 2000); // XXX 4.10.0 max length?
framework.localChange();
framework._.cpNfInner.chainpad.onSettle(function () {
UI.log(Messages.saved);
refreshResponse();
});
},
//keys: []
}, {
className: 'cancel',
name: Messages.cancel,
onClick: function () {},
keys: [27]
}];
APP.responseModal = UI.dialog.customModal(div, { buttons: buttons });
} else {
editor = APP.responseEditor;
setTimeout(function () {
editor.setValue(content.answers.msg || '');
editor.refresh();
editor.save();
editor.focus();
});
}
UI.openCustomModal(APP.responseModal);
});
// $responseMsg.append(btn); // XXX 4.10.0
};
//refreshResponse();
// Allow anonymous answers
var privacyContainer = h('div.cp-form-privacy-container');
var $privacy = $(privacyContainer);
@ -2538,11 +2722,13 @@ define([
evOnChange.reg(refreshPublic);
evOnChange.reg(refreshPrivacy);
evOnChange.reg(refreshEndDate);
//evOnChange.reg(refreshResponse);
return [
endDateContainer,
privacyContainer,
resultsType,
responseMsg
];
};
@ -2594,6 +2780,11 @@ define([
var endDateEl = h('div.alert.alert-warning.cp-burn-after-reading');
var endDate;
var endDateTo;
// numbers greater than this overflow the maximum delay for a setTimeout
// which results in it being executed immediately (oops)
// https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#maximum_delay_value
var MAX_TIMEOUT_DELAY = 2147483647;
var refreshEndDateBanner = function (force) {
if (APP.isEditor) { return; }
var _endDate = content.answers.endDate;
@ -2614,10 +2805,21 @@ define([
APP.isClosed = endDate && endDate < (+new Date());
clearTimeout(endDateTo);
if (!APP.isClosed && endDate) {
setTimeout(function () {
// calculate how many ms in the future the poll will be closed
var diff = (endDate - +new Date() + 100);
// if that value would overflow, then check again in a day
// (if the tab is still open)
if (diff > MAX_TIMEOUT_DELAY) {
endDateTo = setTimeout(function () {
refreshEndDateBanner(true);
}, 1000 * 3600 * 24);
return;
}
endDateTo = setTimeout(function () {
refreshEndDateBanner(true);
$('.cp-form-send-container').find('.cp-open').remove();
},(endDate - +new Date() + 100));
$('.cp-form-send-container').find('.cp-open').hide();
}, diff);
}
};

View File

@ -176,7 +176,7 @@ define([
validateKey: keys.secondaryValidateKey,
owners: [myKeys.edPublic],
crypto: crypto,
Cache: Utils.Cache
//Cache: Utils.Cache // XXX 4.10.0
};
var results = {};
config.onError = function (info) {
@ -265,6 +265,7 @@ define([
}, function (obj) {
if (obj && obj.error) { return void cb(obj); }
var messages = obj.messages;
if (!messages.length) { return void cb(); }
var res = Utils.Crypto.Mailbox.openOwnSecretLetter(messages[0].msg, {
validateKey: data.validateKey,
ephemeral_private: Nacl.util.decodeBase64(answer.curvePrivate),

View File

@ -1326,6 +1326,11 @@ define([
}));
$(waitFor());
}).nThen(function(waitFor) {
// TODO this breaks users' ability to tab out of the editor
// but that's a problem in other editors and nobody has complained so far
// so we'll include this as-is for now while we search for a good pattern
// addresses this issue more generally
Ckeditor.config.tabSpaces = 4;
Ckeditor.config.toolbarCanCollapse = true;
Ckeditor.config.language = Messages._getLanguage();
if (screen.height < 800) {

View File

@ -127,6 +127,7 @@ define([
sframeChan.event("EV_SECURE_ACTION", {
type: parsed.type,
password: data.password,
static: data.static,
href: data.url,
name: data.name
});
@ -214,20 +215,21 @@ define([
$container.html('');
Object.keys(list).forEach(function (id) {
var data = list[id];
var name = data.filename || data.title || '?';
var name = data.filename || data.title || data.name || '?';
if (filter && name.toLowerCase().indexOf(filter.toLowerCase()) === -1) {
return;
}
var $span = $('<span>', {
'class': 'cp-filepicker-content-element',
'title': name,
'title': Util.fixHTML(name),
}).appendTo($container);
$span.append(UI.getFileIcon(data));
$('<span>', {'class': 'cp-filepicker-content-element-name'}).text(name)
.appendTo($span);
if (data.static) { $span.attr('title', Util.fixHTML(data.href)); }
$span.click(function () {
if (typeof onFilePicked === "function") {
onFilePicked({url: data.href, name: name, password: data.password});
onFilePicked({url: data.href, name: name, static: data.static, password: data.password});
}
});

View File

@ -345,7 +345,7 @@ define([
var senderKey = content.sender && content.sender.edPublic;
var fromMe = senderKey === privateData.edPublic;
var fromAdmin = ctx.adminKeys.indexOf(senderKey) !== -1;
var fromPremium = Boolean(content.sender.plan);
var fromPremium = Boolean(content.sender.plan || Util.find(content, ['sender', 'quota', 'plan']));
var userData = h('div.cp-support-showdata', [
Messages.support_showData,

View File

@ -24,7 +24,10 @@ define([
sframeChan.on('Q_DRIVE_USEROBJECT', function (data, cb) {
if (!teamId) { return void cb({error: 'EINVAL'}); }
data.teamId = teamId;
// a teamId of -1 bypasses guards against modifying your drive
// from the team app
if (data.teamId !== -1) { data.teamId = teamId; }
else { delete data.teamId; }
Cryptpad.userObjectCommand(data, cb);
});
sframeChan.on('Q_DRIVE_GETOBJECT', function (data, cb) {