Compare commits
266 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac24fdd4eb | ||
|
|
3fc2a43573 | ||
|
|
31536a48ef | ||
|
|
beec029324 | ||
|
|
f450a5ceaa | ||
|
|
9693d8a651 | ||
|
|
2c0b291902 | ||
|
|
f8c8b41ad8 | ||
|
|
9252c43225 | ||
|
|
85f453998e | ||
|
|
4603cdba7e | ||
|
|
48eb0c2358 | ||
|
|
9357e17b93 | ||
|
|
812f62c8b3 | ||
|
|
1871d00bb2 | ||
|
|
de65a04ae0 | ||
|
|
d6c09eac51 | ||
|
|
62dc6dda49 | ||
|
|
1ce0e8256b | ||
|
|
0a0ac24d62 | ||
|
|
7fb0122ab3 | ||
|
|
d833c70dc7 | ||
|
|
88e90d34b9 | ||
|
|
9962377018 | ||
|
|
5692acdf04 | ||
|
|
dbb4817128 | ||
|
|
1730a9b355 | ||
|
|
ddad11c43a | ||
|
|
e1f091f724 | ||
|
|
35af34049b | ||
|
|
59f7e7d346 | ||
|
|
8e503c9ac7 | ||
|
|
58829b7646 | ||
|
|
6725d921ac | ||
|
|
c6e60ebf0e | ||
|
|
bc3b864754 | ||
|
|
de6f724bc5 | ||
|
|
c955b20131 | ||
|
|
42a5dc2649 | ||
|
|
f289801d23 | ||
|
|
ab95704d2d | ||
|
|
7717337b1e | ||
|
|
da043f163d | ||
|
|
60f33a374d | ||
|
|
f40cbdbd19 | ||
|
|
579e2e8b2b | ||
|
|
7cbee8af5b | ||
|
|
b57c9a85d5 | ||
|
|
e9131b031b | ||
|
|
cefebd87a4 | ||
|
|
70d54b5a5a | ||
|
|
6d51b25fc6 | ||
|
|
b67709a1c8 | ||
|
|
ac6f628c44 | ||
|
|
216d2ec1bf | ||
|
|
de2f1ee0c4 | ||
|
|
b0a84cd7ab | ||
|
|
9869153ae8 | ||
|
|
28ff9670de | ||
|
|
8f26e12c85 | ||
|
|
69ded8b1b4 | ||
|
|
9fec2a1e2a | ||
|
|
5231b27dea | ||
|
|
3697add70c | ||
|
|
c6da0d13cd | ||
|
|
f096472b1d | ||
|
|
bca38200a8 | ||
|
|
a6793a14f1 | ||
|
|
cd0db08b14 | ||
|
|
cc8021a742 | ||
|
|
93f9082071 | ||
|
|
7312189be0 | ||
|
|
094dcac2dc | ||
|
|
db37192857 | ||
|
|
33bd52388a | ||
|
|
d6483a99d0 | ||
|
|
ec866844ac | ||
|
|
26d92b422f | ||
|
|
9faa009f66 | ||
|
|
f1ec67c614 | ||
|
|
649235cfec | ||
|
|
8821b5a903 | ||
|
|
912931e1bc | ||
|
|
788dd48c93 | ||
|
|
9af2aa5566 | ||
|
|
1e2bd553fb | ||
|
|
2d5a33225a | ||
|
|
e61202387e | ||
|
|
e7fb19c8b0 | ||
|
|
62007d3e38 | ||
|
|
c504fa98aa | ||
|
|
69c16ab90d | ||
|
|
b8e25677ef | ||
|
|
e328671f20 | ||
|
|
ce2474c0ad | ||
|
|
51a8748d23 | ||
|
|
be9d1b5411 | ||
|
|
185da99ccb | ||
|
|
5e96f53948 | ||
|
|
4df8a2ac0f | ||
|
|
12756b48a0 | ||
|
|
7910b9e739 | ||
|
|
cfe0f6b56d | ||
|
|
76b1a8379b | ||
|
|
51a1b76a1f | ||
|
|
76e58d05cb | ||
|
|
fa29006311 | ||
|
|
a0717e4424 | ||
|
|
4da430e276 | ||
|
|
f4aa71fc75 | ||
|
|
2580965284 | ||
|
|
cbc62b8e07 | ||
|
|
3134453220 | ||
|
|
95d04386e2 | ||
|
|
8119258c4d | ||
|
|
5c2e64d6a2 | ||
|
|
92658d2ac9 | ||
|
|
44ec83ef28 | ||
|
|
57b9991396 | ||
|
|
cdce66813e | ||
|
|
fd77c78a97 | ||
|
|
8cc387c67f | ||
|
|
e40731574a | ||
|
|
f08e8c8ffc | ||
|
|
498cf1b905 | ||
|
|
03d4f248fd | ||
|
|
bf4c7d409a | ||
|
|
ccd06100d5 | ||
|
|
f0f3f88dd3 | ||
|
|
6e18040da0 | ||
|
|
2a5fe09d16 | ||
|
|
6ddb03fad9 | ||
|
|
756e95867c | ||
|
|
1595162496 | ||
|
|
fc7cf5462f | ||
|
|
b65d9e9e10 | ||
|
|
5bf89b946d | ||
|
|
6f8481cd33 | ||
|
|
f1a2fe74a6 | ||
|
|
2b78b643d8 | ||
|
|
43cf75c075 | ||
|
|
4dc7f5354d | ||
|
|
c78c3f423c | ||
|
|
ec81410b03 | ||
|
|
254da4ad81 | ||
|
|
4cc49a693b | ||
|
|
c808dcea18 | ||
|
|
0d32225bdd | ||
|
|
fe4a0d0fcd | ||
|
|
0581fd3d51 | ||
|
|
e22c637adf | ||
|
|
7157edf4af | ||
|
|
e67cf30dfd | ||
|
|
a6fdac128f | ||
|
|
4c27353154 | ||
|
|
1adcaad04a | ||
|
|
ba91f628c7 | ||
|
|
ea05afdf04 | ||
|
|
3c8c2abd99 | ||
|
|
815d009006 | ||
|
|
af3b18d1f5 | ||
|
|
327e31ae03 | ||
|
|
0500639d01 | ||
|
|
57aabc2a24 | ||
|
|
8de84eea4c | ||
|
|
2df08618e9 | ||
|
|
03484e274a | ||
|
|
ea8a087fd7 | ||
|
|
57e1307a3a | ||
|
|
4de04c460a | ||
|
|
888c84c283 | ||
|
|
b856d9c0f9 | ||
|
|
86378bd0d8 | ||
|
|
aa8ce36b94 | ||
|
|
4e53110350 | ||
|
|
7a49611a94 | ||
|
|
763eca6ca9 | ||
|
|
03dcace09d | ||
|
|
ef52f541fe | ||
|
|
410e2574d1 | ||
|
|
0c0aec3cc9 | ||
|
|
febad410f5 | ||
|
|
b1f58fb1ff | ||
|
|
a537f4a075 | ||
|
|
c7e03f9a71 | ||
|
|
8779e550a4 | ||
|
|
19a434a289 | ||
|
|
66c6423001 | ||
|
|
21ccf45db9 | ||
|
|
5442b38a20 | ||
|
|
ce01a4c5a3 | ||
|
|
801d14280d | ||
|
|
0213aa0b16 | ||
|
|
949d098e99 | ||
|
|
6d138bd3e5 | ||
|
|
fb111d017f | ||
|
|
2ca8ec371e | ||
|
|
162f06bbbb | ||
|
|
d386706382 | ||
|
|
403ae625cd | ||
|
|
559071877e | ||
|
|
20d692bbd6 | ||
|
|
a2130ca106 | ||
|
|
2454eff51d | ||
|
|
4e33c3a970 | ||
|
|
64cdac9294 | ||
|
|
e40af1ca7f | ||
|
|
e183c316dd | ||
|
|
f25cc5a580 | ||
|
|
d44b8981e2 | ||
|
|
5796d9d623 | ||
|
|
d710be866f | ||
|
|
72bd3d22e8 | ||
|
|
e0134111d5 | ||
|
|
69424e4f2f | ||
|
|
8a4aa0e49a | ||
|
|
0f21020783 | ||
|
|
c4cd0fe0c1 | ||
|
|
4ac2db56f8 | ||
|
|
4d1fb5270d | ||
|
|
89897bcf70 | ||
|
|
dae6aa21d8 | ||
|
|
bf14f4cd7b | ||
|
|
e5f28ca78e | ||
|
|
944d590298 | ||
|
|
48175ce1f7 | ||
|
|
a0add8f651 | ||
|
|
c41bfcb9e0 | ||
|
|
630481cb7a | ||
|
|
84e0b68b16 | ||
|
|
93b6fa6036 | ||
|
|
7099d01641 | ||
|
|
f4478aad54 | ||
|
|
a12c2921d7 | ||
|
|
ab18dbfde5 | ||
|
|
1b334b906a | ||
|
|
aa605468b6 | ||
|
|
9c292fbeab | ||
|
|
43caf28e36 | ||
|
|
29925fd303 | ||
|
|
0dfb18fb3b | ||
|
|
750fff16ef | ||
|
|
e3496830f1 | ||
|
|
7e0e380b5a | ||
|
|
458f988262 | ||
|
|
d20be1dd66 | ||
|
|
db3690bffe | ||
|
|
3b9cb9c68c | ||
|
|
378d14af7e | ||
|
|
12d5e870c5 | ||
|
|
9f9b7cb991 | ||
|
|
68d73f2e12 | ||
|
|
4d08461ab1 | ||
|
|
60c9f22129 | ||
|
|
15e29e209c | ||
|
|
d936fcab3b | ||
|
|
868a763cec | ||
|
|
179b747769 | ||
|
|
c7a9faa803 | ||
|
|
1ef34ccb98 | ||
|
|
96cbea3c11 | ||
|
|
6fc45fd941 | ||
|
|
1d718adce4 | ||
|
|
b0c761dfb1 | ||
|
|
d6140b684f | ||
|
|
23f950c60c |
@@ -121,6 +121,7 @@
|
||||
"reactions": false,
|
||||
"realm_icon": false,
|
||||
"realm_logo": false,
|
||||
"realm_night_logo": false,
|
||||
"recent_senders": false,
|
||||
"reload": false,
|
||||
"reload_state": false,
|
||||
|
||||
@@ -11,6 +11,7 @@ from django.utils.timezone import utc as timezone_utc
|
||||
|
||||
from analytics.lib.counts import COUNT_STATS, logger, process_count_stat
|
||||
from scripts.lib.zulip_tools import ENDC, WARNING
|
||||
from zerver.lib.remote_server import send_analytics_to_remote_server
|
||||
from zerver.lib.timestamp import floor_to_hour
|
||||
from zerver.models import Realm
|
||||
|
||||
@@ -84,3 +85,6 @@ class Command(BaseCommand):
|
||||
print("Finished updating analytics counts through %s in %.3fs" %
|
||||
(fill_to_time, time.time() - start))
|
||||
logger.info("Finished updating analytics counts through %s" % (fill_to_time,))
|
||||
|
||||
if settings.PUSH_NOTIFICATION_BOUNCER_URL and settings.SUBMIT_USAGE_STATISTICS:
|
||||
send_analytics_to_remote_server()
|
||||
|
||||
@@ -1024,7 +1024,7 @@ class TestActiveUsersAudit(AnalyticsTestCase):
|
||||
self.assertTrue(UserCount.objects.filter(
|
||||
user=user, property=self.current_property, subgroup='false',
|
||||
end_time=end_time, value=1).exists())
|
||||
self.assertFalse(UserCount.objects.filter(user=user2).exists())
|
||||
self.assertFalse(UserCount.objects.filter(user=user2, end_time=end_time).exists())
|
||||
|
||||
class TestRealmActiveHumans(AnalyticsTestCase):
|
||||
def setUp(self) -> None:
|
||||
|
||||
@@ -52,7 +52,7 @@ author = 'The Zulip Team'
|
||||
# The short X.Y version.
|
||||
version = '2.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '2.0.0-rc1'
|
||||
release = '2.0.0'
|
||||
|
||||
# This allows us to insert a warning that appears only on an unreleased
|
||||
# version, e.g. to say that something is likely to have changed.
|
||||
|
||||
@@ -128,7 +128,7 @@ commit message.
|
||||
performance.
|
||||
- When you fix a GitHub issue, [mark that you've fixed the issue in
|
||||
your commit
|
||||
message](https://help.github.com/articles/closing-issues-via-commit-messages/)
|
||||
message](https://help.github.com/en/articles/closing-issues-via-commit-messages)
|
||||
so that the issue is automatically closed when your code is merged.
|
||||
Zulip's preferred style for this is to have the final paragraph of
|
||||
the commit message read e.g. "Fixes: \#123."
|
||||
|
||||
@@ -43,7 +43,7 @@ followed by the desired labels enclosed within double quotes (`""`).
|
||||
(`""`).
|
||||
|
||||
* **Find unclaimed issues** — Use the [GitHub search
|
||||
feature](https://help.github.com/articles/using-search-to-filter-issues-and-pull-requests/)
|
||||
feature](https://help.github.com/en/articles/using-search-to-filter-issues-and-pull-requests)
|
||||
to find unclaimed issues by adding one of the following filters to your search:
|
||||
|
||||
* `-label: "in progress"` (excludes issues labeled with the **in progress** label)
|
||||
|
||||
@@ -77,7 +77,7 @@ Next, read the following to learn more about developing for Zulip:
|
||||
* [Testing](../testing/testing.html)
|
||||
|
||||
[github-join]: https://github.com/join
|
||||
[github-help-add-ssh-key]: https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/
|
||||
[github-help-add-ssh-key]: https://help.github.com/en/articles/adding-a-new-ssh-key-to-your-github-account
|
||||
[github-zulip-zulip]: https://github.com/zulip/zulip/
|
||||
[github-help-fork]: https://help.github.com/articles/fork-a-repo/
|
||||
[github-help-fork]: https://help.github.com/en/articles/fork-a-repo
|
||||
[gitbook-rebase]: https://git-scm.com/book/en/v2/Git-Branching-Rebasing
|
||||
|
||||
@@ -66,7 +66,7 @@ Follow our [Git Guide][set-up-git] in order to install Git, set up a
|
||||
GitHub account, create an SSH key to access code on GitHub
|
||||
efficiently, etc. Be sure to create an ssh key and add it to your
|
||||
GitHub account using
|
||||
[these instructions](https://help.github.com/articles/generating-an-ssh-key/).
|
||||
[these instructions](https://help.github.com/en/articles/generating-an-ssh-key).
|
||||
|
||||
### Step 1: Install Prerequisites
|
||||
|
||||
@@ -278,11 +278,12 @@ Now you are ready for [Step 2: Get Zulip Code.](#step-2-get-zulip-code)
|
||||
2. Open Terminal (macOS/Ubuntu) or Git BASH (Windows; must
|
||||
**run as an Administrator**).
|
||||
3. In Terminal/Git BASH,
|
||||
[clone your fork of the Zulip repository](../git/cloning.html#step-1b-clone-to-your-machine)
|
||||
and [connect the Zulip upstream repository](../git/cloning.html#step-1c-connect-your-fork-to-zulip-upstream):
|
||||
[clone your fork of the Zulip repository](../git/cloning.html#step-1b-clone-to-your-machine) and
|
||||
[connect the Zulip upstream repository](../git/cloning.html#step-1c-connect-your-fork-to-zulip-upstream):
|
||||
|
||||
```
|
||||
git clone --config pull.rebase git@github.com:YOURUSERNAME/zulip.git
|
||||
cd zulip
|
||||
git remote add -f upstream https://github.com/zulip/zulip.git
|
||||
```
|
||||
|
||||
|
||||
@@ -143,10 +143,10 @@ Zulip.
|
||||

|
||||
|
||||
[gitbook-rebase]: https://git-scm.com/book/en/v2/Git-Branching-Rebasing
|
||||
[github-help-add-ssh-key]: https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/
|
||||
[github-help-conf-remote]: https://help.github.com/articles/configuring-a-remote-for-a-fork/
|
||||
[github-help-fork]: https://help.github.com/articles/fork-a-repo/
|
||||
[github-help-sync-fork]: https://help.github.com/articles/syncing-a-fork/
|
||||
[github-help-add-ssh-key]: https://help.github.com/en/articles/adding-a-new-ssh-key-to-your-github-account
|
||||
[github-help-conf-remote]: https://help.github.com/en/articles/configuring-a-remote-for-a-fork
|
||||
[github-help-fork]: https://help.github.com/en/articles/fork-a-repo
|
||||
[github-help-sync-fork]: https://help.github.com/en/articles/syncing-a-fork
|
||||
[github-zulip]: https://github.com/zulip/
|
||||
[github-zulip-zulip]: https://github.com/zulip/zulip/
|
||||
[travis-ci]: https://travis-ci.org/
|
||||
|
||||
@@ -53,5 +53,5 @@ tools/fetch-rebase-pull-request <PR-number>
|
||||
tools/fetch-pull-request <PR-number>
|
||||
```
|
||||
|
||||
[github-help-co-pr-locally]: https://help.github.com/articles/checking-out-pull-requests-locally/
|
||||
[github-help-co-pr-locally]: https://help.github.com/en/articles/checking-out-pull-requests-locally
|
||||
[tools-PR]: ../git/zulip-tools.html#fetch-a-pull-request-and-rebase
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Fixing Commits
|
||||
This is mostly from
|
||||
[here](https://help.github.com/articles/changing-a-commit-message/#rewriting-the-most-recent-commit-message).
|
||||
[here](https://help.github.com/en/articles/changing-a-commit-message#rewriting-the-most-recent-commit-message).
|
||||
|
||||
## Fixing the last commit
|
||||
### Changing the last commit message
|
||||
|
||||
@@ -143,8 +143,8 @@ explain to the reviewer how you solved any problems they mentioned, and c) ask
|
||||
for another review.
|
||||
|
||||
[edx-howto-rebase-pr]: https://github.com/edx/edx-platform/wiki/How-to-Rebase-a-Pull-Request
|
||||
[github-help-about-pr]: https://help.github.com/articles/about-pull-requests/
|
||||
[github-help-create-pr-fork]: https://help.github.com/articles/creating-a-pull-request-from-a-fork/
|
||||
[github-help-about-pr]: https://help.github.com/en/articles/about-pull-requests
|
||||
[github-help-create-pr-fork]: https://help.github.com/en/articles/creating-a-pull-request-from-a-fork
|
||||
[images-create-pr]: ../images/zulip-open-pr.png
|
||||
[keep-up-to-date]: ../git/using.html#keep-your-fork-up-to-date
|
||||
[push-commits]: ../git/using.html#push-your-commits-to-github
|
||||
|
||||
@@ -63,5 +63,5 @@ And, if none of the above are to your liking, try [one of these][gitbook-guis].
|
||||
[gitgui-gitk]: https://git-scm.com/docs/gitk
|
||||
[gitgui-gitxdev]: https://rowanj.github.io/gitx/
|
||||
[gitgui-sourcetree]: https://www.sourcetreeapp.com/
|
||||
[github-help-add-ssh-key]: https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/
|
||||
[github-help-add-ssh-key]: https://help.github.com/en/articles/adding-a-new-ssh-key-to-your-github-account
|
||||
[tig]: http://jonas.nitro.dk/tig/
|
||||
|
||||
@@ -34,7 +34,7 @@ Here are the top things to know:
|
||||
|
||||
- **Git stores all data as objects, of which there are four types:** blob
|
||||
(file), tree (directory), commit (revision), and tag. Each of these objects
|
||||
is named by a unique hash, the SHA-1 has of its contents. Most of the time
|
||||
is named by a unique hash, the SHA-1 hash of its contents. Most of the time
|
||||
you'll refer to objects by their truncated hash or more human-readable
|
||||
reference like `HEAD` (the current branch). Blobs and trees represent files
|
||||
and directories. Tags are named references to other objects. A commit object
|
||||
|
||||
@@ -277,4 +277,4 @@ whichever branch you need to update.
|
||||
[gitbook-basic-merge-conflicts]: https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging#Basic-Merge-Conflicts
|
||||
[gitbook-git-cherry-pick]: https://git-scm.com/docs/git-cherry-pick
|
||||
[gitbook-reset]: https://git-scm.com/docs/git-reset
|
||||
[github-help-resolve-merge-conflict]: https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/
|
||||
[github-help-resolve-merge-conflict]: https://help.github.com/en/articles/resolving-a-merge-conflict-using-the-command-line
|
||||
|
||||
@@ -442,10 +442,10 @@ complicated rebase.
|
||||
[gitbook-other-envs-bash]: https://git-scm.com/book/en/v2/Git-in-Other-Environments-Git-in-Bash
|
||||
[gitbook-other-envs-zsh]: https://git-scm.com/book/en/v2/Git-in-Other-Environments-Git-in-Zsh
|
||||
[gitbook-rm]: https://git-scm.com/docs/git-rm
|
||||
[github-help-closing-issues]: https://help.github.com/articles/closing-issues-via-commit-messages/
|
||||
[github-help-push]: https://help.github.com/articles/pushing-to-a-remote/
|
||||
[github-help-rebase]: https://help.github.com/articles/using-git-rebase/
|
||||
[github-help-sync-fork]: https://help.github.com/articles/syncing-a-fork/
|
||||
[github-help-closing-issues]: https://help.github.com/en/articles/closing-issues-via-commit-messages
|
||||
[github-help-push]: https://help.github.com/en/articles/pushing-to-a-remote
|
||||
[github-help-rebase]: https://help.github.com/en/articles/using-git-rebase
|
||||
[github-help-sync-fork]: https://help.github.com/en/articles/syncing-a-fork
|
||||
[how-git-is-different]: ./the-git-difference.html
|
||||
[zulip-git-guide-up-to-date]: ../git/using.html#keep-your-fork-up-to-date
|
||||
[zulip-rtd-commit-discipline]: ../contributing/version-control.html#commit-discipline
|
||||
|
||||
@@ -115,6 +115,33 @@ Switched to a new branch 'review-original-5156'
|
||||
HEAD is now at 5a1e982 tools: Update clean-branches to clean review branches.
|
||||
```
|
||||
|
||||
## Push to a pull request
|
||||
|
||||
`tools/push-to-pull-request` is primarily useful for maintainers who
|
||||
are merging other users' commits into a Zulip repository. After doing
|
||||
`reset-to-pull-request` or `fetch-pull-request` and making some
|
||||
changes, you can push a branch back to a pull request with e.g.
|
||||
`tools/push-to-pull-rqeuest 1234`. This is useful for a few things:
|
||||
|
||||
* Getting CI to run and enabling you to use the GitHub "Merge" buttons
|
||||
to merge a PR after you make some corrections to a PR, without
|
||||
waiting for an extra round trip with the PR author.
|
||||
* For commits that aren't ready to merge yet, communicating clearly
|
||||
any changes you'd like to see happen that are easier for you to
|
||||
explain by just editing the code than in words.
|
||||
* Saving a contributor from needing to duplicate any rebase work that
|
||||
you did as part of integrating parts of the PR.
|
||||
|
||||
You'll likely want to comment on the PR after doing so, to ensure that
|
||||
the original contributor knows to pull your changes rather than
|
||||
accidentally overwriting them with a force push when they make their
|
||||
next batch of changes.
|
||||
|
||||
Note that in order to do this you need permission to do such a push,
|
||||
which GitHub offers by default to users with write access to the
|
||||
repository. For multiple developers collaborating on a PR, you can
|
||||
achieve this by granting other users permission to write to your fork.
|
||||
|
||||
## Delete unimportant branches
|
||||
|
||||
`tools/clean-branches` is a shell script that removes branches that are either:
|
||||
|
||||
@@ -7,7 +7,7 @@ All notable changes to the Zulip server are documented in this file.
|
||||
This section lists notable unreleased changes; it is generally updated
|
||||
in bursts.
|
||||
|
||||
### 2.0.0-rc1 -- 2019-02-11
|
||||
### 2.0.0 -- 2019-03-01
|
||||
|
||||
**Highlights:**
|
||||
- Added automation for synchronizing user avatars, custom profile
|
||||
@@ -15,19 +15,33 @@ in bursts.
|
||||
- Added support for explicitly setting oneself as "away" and "user
|
||||
status" messages.
|
||||
- Added a built-in /poll slash command for lightweight polls.
|
||||
- Added support for using Zoom as the video chat provider. We now
|
||||
support Jitsi, Google Hangouts, and Zoom.
|
||||
- Added support for branding the top-right corner of the logged in app
|
||||
- Added experimental support for using Zoom as the video chat
|
||||
provider. We now support Jitsi, Google Hangouts, and Zoom.
|
||||
- Added support for branding the top-left corner of the logged in app
|
||||
with an organization's logo.
|
||||
- Zulip's "Guest users" feature is no longer experimental.
|
||||
- The HipChat/Stride data import tool is no longer experimental.
|
||||
Our HipChat and Slack import tools are now well-tested with millions
|
||||
of messages, 10,000s of users, and 100,000s of uploaded files.
|
||||
- Added a built-in tool for backups and restoration.
|
||||
- Deprecated support for Ubuntu Trusty. Zulip 2.0.x will continue to
|
||||
support Ubuntu Trusty, but Zulip 2.1.0 will remove support for
|
||||
installing on Trusty.
|
||||
|
||||
**Upgrade notes:**
|
||||
- This release adds support for [submitting basic usage statistics] to
|
||||
help the Zulip core team. This feature can be enabled only if a server
|
||||
is using the [Mobile Push Notification Service][mpns-statistics-docs],
|
||||
and is enabled by default in that case. To disable it, set
|
||||
`SUBMIT_USAGE_STATISTICS = False` in `/etc/zulip/settings.py`.
|
||||
|
||||
[mpns-statistics-docs]: ../production/mobile-push-notifications.html#submitting-statistics
|
||||
|
||||
**Full feature changelog:**
|
||||
- Added support for CentOS 7 in the development environment
|
||||
provisioning process. This is an important step towards production
|
||||
CentOS/RHEL 7 support.
|
||||
- Added a new invitation workflow with reusable links.
|
||||
- Added a new Azure Active Directory authentication integration.
|
||||
New authentication backends supported by python-social-auth can now be
|
||||
added with just a few dozen lines of code.
|
||||
@@ -46,6 +60,7 @@ in bursts.
|
||||
- Added Ctrl+. shortcut for narrowing to current compose recipient.
|
||||
- Added icons to indicate which "organization settings" tabs are
|
||||
available to regular users.
|
||||
- Added a tool for migrating from S3 to the local file uploads backend.
|
||||
- Added protocol for communicating version incompatibility to mobile apps.
|
||||
- Added support for copying avatar and other profile data when
|
||||
creating a second account on a Zulip server with a given email address.
|
||||
@@ -55,10 +70,14 @@ in bursts.
|
||||
- Added a ReviewBoard integration, and improved numerous existing integrations.
|
||||
- Added support for multi-line messages for the /me feature.
|
||||
- Added markdown rendering of text when displaying custom profile fields.
|
||||
- Added "silent mentions" syntax (_@**Tim Abbott**), which show
|
||||
visually, but don't trigger a notification for the target user.
|
||||
- Added "silent mentions" syntax (`@_**Tim Abbott**`), which show
|
||||
visually, but don't trigger a notification to the target user.
|
||||
- Added support for using lightbox in compose preview.
|
||||
- Changes in date no longer force a repeated recipient bar. This
|
||||
fixes a common source of confusion for new users.
|
||||
- Suppressed notifications when quoting a message mentioning yourself.
|
||||
- Message editing now has the compose widgets for emoji, video calls, etc.
|
||||
- Message editing now has a markdown preview feature just like compose.
|
||||
- Message editing now uses same "enter-sends" behavior as compose.
|
||||
- Organization administrators can now edit users' custom profile fields.
|
||||
- Optimized performance of data import from Slack, HipChat, etc.
|
||||
@@ -74,8 +93,9 @@ in bursts.
|
||||
- Fixed missing API authentication headers for mobile file access.
|
||||
- Fixed various select and copy-paste issues.
|
||||
- Fixed various back button bugs in settings UI.
|
||||
- Fixed various mobile web visual issues.
|
||||
- Fixed unnecessary resizing of animated custom emoji.
|
||||
- Fixed some performance issues for organizations with 1000s of streams.
|
||||
- Fixed several performance issues for organizations with 1000s of streams.
|
||||
- Fixed various error handling bugs sending push notifications.
|
||||
- Fixed handling of diacritics in user-mention typeahead.
|
||||
- Fixed several bugs with importing data into Zulip's S3 backend.
|
||||
|
||||
@@ -265,6 +265,16 @@ installation. Then, run as root:
|
||||
/home/zulip/deployments/current/scripts/setup/restore-backup /path/to/backup
|
||||
```
|
||||
|
||||
If you're not sure what versions were in use when a given backup was
|
||||
created, you can get that information via the files in the backup
|
||||
tarball `postgres-version`, `os-version`, and `zulip-version`. The
|
||||
following command may be useful for viewing these files without
|
||||
extracting the entire archive.
|
||||
|
||||
```
|
||||
tar -Oaxf /path/to/archive/zulip-backup-rest.tar.gz zulip-backup/zulip-version
|
||||
```
|
||||
|
||||
[install-server]: ../production/install.html
|
||||
|
||||
### What is included
|
||||
|
||||
@@ -130,6 +130,21 @@ and privacy in mind:
|
||||
If you have any questions about the security model, contact
|
||||
support@zulipchat.com.
|
||||
|
||||
## Submitting statistics
|
||||
|
||||
Systems using the Mobile Push Notifications Service will, by default,
|
||||
submit basic usage statistics (e.g. Zulip version, number of users,
|
||||
number of messages sent) to the service. These statistics help the
|
||||
Zulip open source project understand how many people are using Zulip,
|
||||
and help us allocate resources towards supporting self-hosted
|
||||
installations.
|
||||
|
||||
Our use of these statistics is governed by the same ToS and
|
||||
Privacy Policy that covers the Mobile Push Notifications Service
|
||||
itself. If your organization does not want to submit these
|
||||
statistics, you can disable this feature at any time by setting
|
||||
`SUBMIT_USAGE_STATISTICS=False` in `/etc/zulip/settings.py`.
|
||||
|
||||
## Legacy signup
|
||||
|
||||
Here are legacy instructions for signing a server up for push
|
||||
|
||||
@@ -8,7 +8,8 @@ The default is the `LOCAL_UPLOADS_DIR` backend, which just stores
|
||||
files on disk in the specified directory on the Zulip server.
|
||||
Obviously, this backend doesn't work with multiple Zulip servers and
|
||||
doesn't scale, but it's great for getting a Zulip server up and
|
||||
running quickly.
|
||||
running quickly. You can later migrate the uploads to S3 by
|
||||
[following the instructions here](#migrating-from-local-uploads-to-amazon-s3-backend).
|
||||
|
||||
We also support an `S3` backend, which uses the Python `boto` library
|
||||
to upload files to Amazon S3 (and, with some work, it should be
|
||||
@@ -139,3 +140,26 @@ need a block like this:
|
||||
The file-uploads bucket should not be world-readable. See the
|
||||
[documentation on the Zulip security model](security-model.html) for
|
||||
details on the security model for uploaded files.
|
||||
|
||||
## Migrating from local uploads to Amazon S3 backend
|
||||
|
||||
As you scale your server, you might want to migrate the uploads from
|
||||
your local backend to Amazon S3. Follow these instructions, step by
|
||||
step, to do the migration.
|
||||
|
||||
1. First, [setup the S3 backend](#s3-backend-configuration) in the settings
|
||||
(all the auth stuff), but leave `LOCAL_UPLOADS_DIR` set -- the
|
||||
migration tool will need that value to know where to find your uploads.
|
||||
2. Run `./manage.py transfer_uploads_to_s3`. This will upload all the
|
||||
files from the local uploads directory to Amazon S3. By default,
|
||||
this command runs on 6 parallel processes, since uploading is a
|
||||
latency-sensitive operation. You can control this parameter using
|
||||
the `--processes` option.
|
||||
3. Once the transer script compltes, disable `LOCAL_UPLOADS_DIR`, and
|
||||
restart your server (continuing the last few steps of the S3
|
||||
backend setup instructions).
|
||||
|
||||
Congratulations! Your uploaded files are now migrated to S3.
|
||||
|
||||
**Caveat**: The current version of this tool does not migrate an
|
||||
uploaded organization avatar or logo.
|
||||
|
||||
@@ -233,7 +233,7 @@ from the SSH session.
|
||||
[mypy-docs]: ../testing/mypy.html
|
||||
[requirements-readme]: https://github.com/zulip/zulip/blob/master/requirements/README.md
|
||||
[stack-overflow]: https://askubuntu.com/questions/8653/how-to-keep-processes-running-after-ending-ssh-session
|
||||
[caching]: https://help.github.com/articles/caching-your-github-password-in-git/
|
||||
[caching]: https://help.github.com/en/articles/caching-your-github-password-in-git
|
||||
|
||||
## JavaScript and other frontend packages
|
||||
|
||||
@@ -251,7 +251,7 @@ reasoning here.
|
||||
repository. We use the standard `package.json` file to declare our
|
||||
direct dependencies, with sections for development and
|
||||
production. Yarn takes care of pinning the versions of indirect
|
||||
dependencies in the `yarn.lock` file; `yarn upgrade` updates the
|
||||
dependencies in the `yarn.lock` file; `yarn install` updates the
|
||||
`yarn.lock` files.
|
||||
* `tools/update-prod-static`. This process is discussed in detail in
|
||||
the [static asset pipeline](../subsystems/front-end-build-process.html) article,
|
||||
|
||||
@@ -213,21 +213,33 @@ request; the logic is in `zerver/views/events_register.py` and
|
||||
change event, it finds the user data in the `realm_user` data
|
||||
struture, and updates it to have the new name.
|
||||
|
||||
This achieves everything we desire, at the cost that we need to write
|
||||
the `apply_events` function. This is a difficult function to
|
||||
implement correctly, because the situations that it tests for almost
|
||||
never happen (being race conditions). So we have a special test
|
||||
class, `EventsRegisterTest`, that is specifically designed to test
|
||||
this function by ensuring the possible race condition always happens.
|
||||
In particular, it does the following:
|
||||
### Testing
|
||||
|
||||
The design above achieves everything we desire, at the cost that we
|
||||
need to write a correct `apply_events` function. This is a difficult
|
||||
function to implement correctly, because the situations that it tests
|
||||
for almost never happen (being race conditions). So we have a special
|
||||
test class, `EventsRegisterTest`, that is specifically designed to
|
||||
test this function by ensuring the possible race condition always
|
||||
happens. In particular, it does the following:
|
||||
|
||||
* Call `fetch_initial_state_data` to get the current state.
|
||||
* Call a state change function that issues an event,
|
||||
e.g. `do_change_full_name`, and capture any events that are generated.
|
||||
* Call `apply_events(state, events)`, and compare the result to
|
||||
calling `fetch_initial_state_data` again now.
|
||||
* Call `apply_events(state, events)`, and compare the resulting
|
||||
"hybrid state" to what one would get from calling
|
||||
`fetch_initial_state_data` again now.
|
||||
|
||||
The `apply_events` code is correct if those two results are identical.
|
||||
The `EventsRegisterTest` tests in `test_events` will print a diff
|
||||
between the "hybrid state" and the "normal state" obtained from
|
||||
calling `fetch_initial_state_data` after the changes. Those tests
|
||||
also inspect the events generated to ensure they have the expected
|
||||
format and `do_test` has the `state_change_expected` and `num_events`
|
||||
arguments that configure how many events that it asserts were
|
||||
generated and whether it expects the state after applying the events
|
||||
to differ what what it was before (which help catch common classes of
|
||||
bugs).
|
||||
|
||||
The final detail we need to ensure that `apply_events` always works
|
||||
correctly is to make sure that we have `EventsRegisterTest` tests for
|
||||
|
||||
@@ -46,9 +46,11 @@ However, if you would like to fix the orientation of a hotspot popover, a
|
||||
### Step 3: Test manually
|
||||
|
||||
To test your hotspot in the development environment, set
|
||||
`ALWAYS_SEND_ALL_HOTSPOTS = True` in `zproject/dev_settings.py`,
|
||||
and invoke `hotspots.initialize()` in your browser
|
||||
console. Every hotspot should be displayed.
|
||||
`ALWAYS_SEND_ALL_HOTSPOTS = True` in `zproject/dev_settings.py`, and
|
||||
invoke `hotspots.initialize()` in your browser console. Every hotspot
|
||||
should be displayed. Note that this setting has a bug that can result
|
||||
in multiple copies of hotspots appearing; you can clear that by
|
||||
reloading the browser.
|
||||
|
||||
Here are some visual characteristics to confirm:
|
||||
- popover content is readable
|
||||
|
||||
@@ -51,6 +51,14 @@ iterative development, but you can override this behavior with the
|
||||
the `--rerun` option, which will rerun just the tests that failed in
|
||||
the last test run.
|
||||
|
||||
**Webhook integrations**. For performance, `test-backend` with no
|
||||
arguments will not run webhook integration tests (`zerver/webhooks/`),
|
||||
which would otherwise account for about 25% of the total runtime.
|
||||
When working on webhooks, we recommend instead running `test-backend
|
||||
zerver/webhooks` manually (or better, the direction for the specific
|
||||
webhooks you're working on). And of course our CI is configured to
|
||||
always use `test-backend --include-webhooks` and run all of the tests.
|
||||
|
||||
## Writing tests
|
||||
|
||||
Before you write your first tests of Zulip, it is worthwhile to read
|
||||
|
||||
@@ -668,12 +668,3 @@ documenting the feature to `templates/zerver/help/` in the main Zulip
|
||||
server repository, where the source for Zulip's user documentation is
|
||||
stored. For information on writing user documentation, see
|
||||
[Zulip's general user guide documentation](../subsystems/user-docs.html).
|
||||
|
||||
For a more concrete example of writing documentation for a new
|
||||
feature, see [an example commit in the Zulip repo][example-commit]
|
||||
that documented a realm feature, [the current source][example-current-source],
|
||||
and [the final rendered documentation][example-docs].
|
||||
|
||||
[example-commit]: https://github.com/zulip/zulip/commit/ce1875533e27a6ec5aab02260dde5f76976ff326
|
||||
[example-current-source]: https://github.com/zulip/zulip/blob/master/templates/zerver/help/manage-who-can-join-and-invite.md
|
||||
[example-docs]: https://chat.zulip.org/help/manage-who-can-join-and-invite
|
||||
|
||||
@@ -35,6 +35,10 @@ const _scroll_util = {
|
||||
scroll_element_into_container: () => {},
|
||||
};
|
||||
|
||||
const _pm_list = {
|
||||
update_private_messages: () => {},
|
||||
};
|
||||
|
||||
const _popovers = {
|
||||
hide_all_except_userlist_sidebar: function () {},
|
||||
hide_all: function () {},
|
||||
@@ -67,6 +71,7 @@ set_global('document', _document);
|
||||
set_global('feature_flags', _feature_flags);
|
||||
set_global('keydown_util', _keydown_util);
|
||||
set_global('page_params', _page_params);
|
||||
set_global('pm_list', _pm_list);
|
||||
set_global('popovers', _popovers);
|
||||
set_global('reload_state', _reload_state);
|
||||
set_global('resize', _resize);
|
||||
@@ -173,7 +178,7 @@ run_test('get_status', () => {
|
||||
run_test('reload_defaults', () => {
|
||||
blueslip.set_test_data('warn', 'get_filter_text() is called before initialization');
|
||||
assert.equal(activity.get_filter_text(), '');
|
||||
assert(blueslip.get_test_logs('warn').length, 1);
|
||||
assert.equal(blueslip.get_test_logs('warn').length, 1);
|
||||
blueslip.clear_test_data();
|
||||
});
|
||||
|
||||
@@ -286,7 +291,7 @@ run_test('huddle_fraction_present', () => {
|
||||
presence.presence_info = presence_info;
|
||||
|
||||
assert.equal(
|
||||
activity.huddle_fraction_present(huddle),
|
||||
buddy_data.huddle_fraction_present(huddle),
|
||||
'0.50');
|
||||
|
||||
huddle = 'alice@zulip.com,fred@zulip.com,jill@zulip.com,mark@zulip.com';
|
||||
@@ -299,7 +304,7 @@ run_test('huddle_fraction_present', () => {
|
||||
presence.presence_info = presence_info;
|
||||
|
||||
assert.equal(
|
||||
activity.huddle_fraction_present(huddle),
|
||||
buddy_data.huddle_fraction_present(huddle),
|
||||
false);
|
||||
});
|
||||
|
||||
@@ -607,7 +612,7 @@ run_test('insert_one_user_into_empty_list', () => {
|
||||
clear_buddy_list();
|
||||
activity.redraw_user(alice.user_id);
|
||||
assert(appended_html.indexOf('data-user-id="1"') > 0);
|
||||
assert(appended_html.indexOf('user_active') > 0);
|
||||
assert(appended_html.indexOf('user_circle_green') > 0);
|
||||
});
|
||||
|
||||
reset_setup();
|
||||
@@ -622,11 +627,11 @@ run_test('insert_alice_then_fred', () => {
|
||||
|
||||
activity.redraw_user(alice.user_id);
|
||||
assert(appended_html.indexOf('data-user-id="1"') > 0);
|
||||
assert(appended_html.indexOf('user_active') > 0);
|
||||
assert(appended_html.indexOf('user_circle_green') > 0);
|
||||
|
||||
activity.redraw_user(fred.user_id);
|
||||
assert(appended_html.indexOf('data-user-id="2"') > 0);
|
||||
assert(appended_html.indexOf('user_active') > 0);
|
||||
assert(appended_html.indexOf('user_circle_green') > 0);
|
||||
});
|
||||
|
||||
reset_setup();
|
||||
@@ -641,7 +646,7 @@ run_test('insert_fred_then_alice_then_rename', () => {
|
||||
|
||||
activity.redraw_user(fred.user_id);
|
||||
assert(appended_html.indexOf('data-user-id="2"') > 0);
|
||||
assert(appended_html.indexOf('user_active') > 0);
|
||||
assert(appended_html.indexOf('user_circle_green') > 0);
|
||||
|
||||
var fred_stub = $.create('fred-first');
|
||||
buddy_list_add(fred.user_id, fred_stub);
|
||||
@@ -653,7 +658,7 @@ run_test('insert_fred_then_alice_then_rename', () => {
|
||||
|
||||
activity.redraw_user(alice.user_id);
|
||||
assert(inserted_html.indexOf('data-user-id="1"') > 0);
|
||||
assert(inserted_html.indexOf('user_active') > 0);
|
||||
assert(inserted_html.indexOf('user_circle_green') > 0);
|
||||
|
||||
// Next rename fred to Aaron.
|
||||
const fred_with_new_name = {
|
||||
@@ -811,8 +816,8 @@ run_test('update_presence_info', () => {
|
||||
blueslip.set_test_data('warn', 'unknown email: foo@bar.com');
|
||||
blueslip.set_test_data('error', 'Unknown email for get_user_id: foo@bar.com');
|
||||
activity.update_presence_info('foo@bar.com', info, server_time);
|
||||
assert(blueslip.get_test_logs('warn').length, 1);
|
||||
assert(blueslip.get_test_logs('error').length, 1);
|
||||
assert.equal(blueslip.get_test_logs('warn').length, 1);
|
||||
assert.equal(blueslip.get_test_logs('error').length, 1);
|
||||
blueslip.clear_test_data();
|
||||
});
|
||||
|
||||
|
||||
@@ -77,6 +77,20 @@ function activate_people() {
|
||||
make_people();
|
||||
activate_people();
|
||||
|
||||
run_test('user_circle', () => {
|
||||
assert.equal(buddy_data.get_user_circle_class(selma.user_id), 'user_circle_green');
|
||||
user_status.set_away(selma.user_id);
|
||||
assert.equal(buddy_data.get_user_circle_class(selma.user_id), 'user_circle_empty_line');
|
||||
user_status.revoke_away(selma.user_id);
|
||||
assert.equal(buddy_data.get_user_circle_class(selma.user_id), 'user_circle_green');
|
||||
|
||||
assert.equal(buddy_data.get_user_circle_class(me.user_id), 'user_circle_green');
|
||||
user_status.set_away(me.user_id);
|
||||
assert.equal(buddy_data.get_user_circle_class(me.user_id), 'user_circle_empty_line');
|
||||
user_status.revoke_away(me.user_id);
|
||||
assert.equal(buddy_data.get_user_circle_class(me.user_id), 'user_circle_green');
|
||||
});
|
||||
|
||||
run_test('buddy_status', () => {
|
||||
assert.equal(buddy_data.buddy_status(selma.user_id), 'active');
|
||||
user_status.set_away(selma.user_id);
|
||||
@@ -143,7 +157,7 @@ run_test('bulk_data_hacks', () => {
|
||||
run_test('level', () => {
|
||||
assert.equal(buddy_data.my_user_status(me.user_id), 'translated: (you)');
|
||||
user_status.set_away(me.user_id);
|
||||
assert.equal(buddy_data.my_user_status(me.user_id), 'translated: (away)');
|
||||
assert.equal(buddy_data.my_user_status(me.user_id), 'translated: (unavailable)');
|
||||
user_status.revoke_away(me.user_id);
|
||||
assert.equal(buddy_data.my_user_status(me.user_id), 'translated: (you)');
|
||||
});
|
||||
|
||||
@@ -106,6 +106,31 @@ run_test('smart_insert', () => {
|
||||
assert.equal(textbox.val(), ':octopus: abc :smile: :airplane: :heart: ');
|
||||
assert(textbox.focused);
|
||||
|
||||
// Test handling of spaces for ```quote
|
||||
textbox = make_textbox('');
|
||||
textbox.caret(0);
|
||||
textbox.blur();
|
||||
compose_ui.smart_insert(textbox, '```quote\nquoted message\n```\n');
|
||||
assert.equal(textbox.insert_text, '```quote\nquoted message\n```\n');
|
||||
assert.equal(textbox.val(), '```quote\nquoted message\n```\n');
|
||||
assert(textbox.focused);
|
||||
|
||||
textbox = make_textbox('');
|
||||
textbox.caret(0);
|
||||
textbox.blur();
|
||||
compose_ui.smart_insert(textbox, "[Quoting…]\n");
|
||||
assert.equal(textbox.insert_text, '[Quoting…]\n');
|
||||
assert.equal(textbox.val(), '[Quoting…]\n');
|
||||
assert(textbox.focused);
|
||||
|
||||
textbox = make_textbox('abc');
|
||||
textbox.caret(3);
|
||||
textbox.blur();
|
||||
compose_ui.smart_insert(textbox, " test with space");
|
||||
assert.equal(textbox.insert_text, ' test with space ');
|
||||
assert.equal(textbox.val(), 'abc test with space ');
|
||||
assert(textbox.focused);
|
||||
|
||||
// Note that we don't have any special logic for strings that are
|
||||
// already surrounded by spaces, since we are usually inserting things
|
||||
// like emojis and file links.
|
||||
|
||||
@@ -316,7 +316,7 @@ run_test('content_typeahead_selected', () => {
|
||||
var document_stub_trigger1_called = false;
|
||||
$('document-stub').trigger = function (event, params) {
|
||||
assert.equal(event, 'usermention_completed.zulip');
|
||||
assert.deepEqual(params, { mentioned: othello });
|
||||
assert.deepEqual(params, { mentioned: othello, is_silent: false });
|
||||
document_stub_trigger1_called = true;
|
||||
};
|
||||
|
||||
@@ -326,6 +326,12 @@ run_test('content_typeahead_selected', () => {
|
||||
expected_value = '@**Othello, the Moor of Venice** ';
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
fake_this.query = 'Hello @oth';
|
||||
fake_this.token = 'oth';
|
||||
actual_value = ct.content_typeahead_selected.call(fake_this, othello);
|
||||
expected_value = 'Hello @**Othello, the Moor of Venice** ';
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
fake_this.query = '@**oth';
|
||||
fake_this.token = 'oth';
|
||||
actual_value = ct.content_typeahead_selected.call(fake_this, othello);
|
||||
@@ -343,26 +349,32 @@ run_test('content_typeahead_selected', () => {
|
||||
var document_stub_trigger3_called = false;
|
||||
$('document-stub').trigger = function (event, params) {
|
||||
assert.equal(event, 'usermention_completed.zulip');
|
||||
assert.deepEqual(params, { mentioned: hamlet });
|
||||
assert.deepEqual(params, { mentioned: hamlet, is_silent: true });
|
||||
document_stub_trigger3_called = true;
|
||||
};
|
||||
|
||||
fake_this.query = '_@kin';
|
||||
fake_this.query = '@_kin';
|
||||
fake_this.token = 'kin';
|
||||
actual_value = ct.content_typeahead_selected.call(fake_this, hamlet);
|
||||
expected_value = '_@**King Hamlet** ';
|
||||
expected_value = '@_**King Hamlet** ';
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
fake_this.query = '_@*kin';
|
||||
fake_this.query = 'Hello @_kin';
|
||||
fake_this.token = 'kin';
|
||||
actual_value = ct.content_typeahead_selected.call(fake_this, hamlet);
|
||||
expected_value = '_@**King Hamlet** ';
|
||||
expected_value = 'Hello @_**King Hamlet** ';
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
fake_this.query = '_@**kin';
|
||||
fake_this.query = '@_*kin';
|
||||
fake_this.token = 'kin';
|
||||
actual_value = ct.content_typeahead_selected.call(fake_this, hamlet);
|
||||
expected_value = '_@**King Hamlet** ';
|
||||
expected_value = '@_**King Hamlet** ';
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
fake_this.query = '@_**kin';
|
||||
fake_this.token = 'kin';
|
||||
actual_value = ct.content_typeahead_selected.call(fake_this, hamlet);
|
||||
expected_value = '@_**King Hamlet** ';
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
// user group mention
|
||||
@@ -400,6 +412,12 @@ run_test('content_typeahead_selected', () => {
|
||||
expected_value = '#**Sweden** ';
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
fake_this.query = 'Hello #swed';
|
||||
fake_this.token = 'swed';
|
||||
actual_value = ct.content_typeahead_selected.call(fake_this, sweden_stream);
|
||||
expected_value = 'Hello #**Sweden** ';
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
fake_this.query = '#**swed';
|
||||
fake_this.token = 'swed';
|
||||
actual_value = ct.content_typeahead_selected.call(fake_this, sweden_stream);
|
||||
@@ -415,6 +433,12 @@ run_test('content_typeahead_selected', () => {
|
||||
expected_value = '~~~python\n\n~~~';
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
fake_this.query = 'Hello ~~~p';
|
||||
fake_this.token = 'p';
|
||||
actual_value = ct.content_typeahead_selected.call(fake_this, 'python');
|
||||
expected_value = 'Hello ~~~python\n\n~~~';
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
fake_this.query = '```p';
|
||||
fake_this.token = 'p';
|
||||
actual_value = ct.content_typeahead_selected.call(fake_this, 'python');
|
||||
@@ -1110,7 +1134,8 @@ run_test('begins_typeahead', () => {
|
||||
};
|
||||
});
|
||||
|
||||
var people_with_all = global.people.get_realm_persons().concat(all_items);
|
||||
var people_only = global.people.get_realm_persons();
|
||||
var people_with_all = people_only.concat(all_items);
|
||||
var all_mentions = people_with_all.concat(global.user_groups.get_realm_user_groups());
|
||||
var lang_list = Object.keys(pygments_data.langs);
|
||||
|
||||
@@ -1128,39 +1153,39 @@ run_test('begins_typeahead', () => {
|
||||
assert_typeahead_equals("#foo\n~~~py", lang_list);
|
||||
|
||||
assert_typeahead_equals("@", false);
|
||||
assert_typeahead_equals("_@", false);
|
||||
assert_typeahead_equals("@_", false);
|
||||
assert_typeahead_equals(" @", false);
|
||||
assert_typeahead_equals(" _@", false);
|
||||
assert_typeahead_equals(" @_", false);
|
||||
assert_typeahead_equals("test @**o", all_mentions);
|
||||
assert_typeahead_equals("test _@**o", all_mentions);
|
||||
assert_typeahead_equals("test @_**o", people_only);
|
||||
assert_typeahead_equals("test @*o", all_mentions);
|
||||
assert_typeahead_equals("test _@*k", all_mentions);
|
||||
assert_typeahead_equals("test @_*k", people_only);
|
||||
assert_typeahead_equals("test @*h", all_mentions);
|
||||
assert_typeahead_equals("test _@*h", all_mentions);
|
||||
assert_typeahead_equals("test @_*h", people_only);
|
||||
assert_typeahead_equals("test @", false);
|
||||
assert_typeahead_equals("test _@", false);
|
||||
assert_typeahead_equals("test @_", false);
|
||||
assert_typeahead_equals("test no@o", false);
|
||||
assert_typeahead_equals("test no_@k", false);
|
||||
assert_typeahead_equals("test no@_k", false);
|
||||
assert_typeahead_equals("@ ", false);
|
||||
assert_typeahead_equals("_@ ", false);
|
||||
assert_typeahead_equals("@_ ", false);
|
||||
assert_typeahead_equals("@* ", false);
|
||||
assert_typeahead_equals("_@* ", false);
|
||||
assert_typeahead_equals("@_* ", false);
|
||||
assert_typeahead_equals("@** ", false);
|
||||
assert_typeahead_equals("_@** ", false);
|
||||
assert_typeahead_equals("@_** ", false);
|
||||
assert_typeahead_equals("test\n@i", all_mentions);
|
||||
assert_typeahead_equals("test\n_@i", all_mentions);
|
||||
assert_typeahead_equals("test\n@_i", people_only);
|
||||
assert_typeahead_equals("test\n @l", all_mentions);
|
||||
assert_typeahead_equals("test\n _@l", all_mentions);
|
||||
assert_typeahead_equals("test\n @_l", people_only);
|
||||
assert_typeahead_equals("@zuli", all_mentions);
|
||||
assert_typeahead_equals("_@zuli", all_mentions);
|
||||
assert_typeahead_equals("@_zuli", people_only);
|
||||
assert_typeahead_equals("@ zuli", false);
|
||||
assert_typeahead_equals("_@ zuli", false);
|
||||
assert_typeahead_equals("@_ zuli", false);
|
||||
assert_typeahead_equals(" @zuli", all_mentions);
|
||||
assert_typeahead_equals(" _@zuli", all_mentions);
|
||||
assert_typeahead_equals(" @_zuli", people_only);
|
||||
assert_typeahead_equals("test @o", all_mentions);
|
||||
assert_typeahead_equals("test _@k", all_mentions);
|
||||
assert_typeahead_equals("test @_o", people_only);
|
||||
assert_typeahead_equals("test @z", all_mentions);
|
||||
assert_typeahead_equals("test _@z", all_mentions);
|
||||
assert_typeahead_equals("test @_z", people_only);
|
||||
|
||||
assert_typeahead_equals(":", false);
|
||||
assert_typeahead_equals(": ", false);
|
||||
|
||||
@@ -296,6 +296,16 @@ var event_fixtures = {
|
||||
},
|
||||
},
|
||||
|
||||
realm__update_dict__night_logo: {
|
||||
type: 'realm',
|
||||
op: 'update_dict',
|
||||
property: 'night_logo',
|
||||
data: {
|
||||
night_logo_url: 'night_logo.png',
|
||||
night_logo_source: 'U',
|
||||
},
|
||||
},
|
||||
|
||||
realm__deactivated: {
|
||||
type: 'realm',
|
||||
op: 'deactivated',
|
||||
@@ -940,6 +950,12 @@ with_overrides(function (override) {
|
||||
assert_same(page_params.realm_logo_url, 'logo.png');
|
||||
assert_same(page_params.realm_logo_source, 'U');
|
||||
|
||||
event = event_fixtures.realm__update_dict__night_logo;
|
||||
override('realm_logo.rerender', noop);
|
||||
dispatch(event);
|
||||
assert_same(page_params.realm_night_logo_url, 'night_logo.png');
|
||||
assert_same(page_params.realm_night_logo_source, 'U');
|
||||
|
||||
event = event_fixtures.realm__deactivated;
|
||||
window.location = {};
|
||||
dispatch(event);
|
||||
@@ -1336,6 +1352,7 @@ with_overrides(function (override) {
|
||||
event = event_fixtures.update_display_settings__night_mode;
|
||||
page_params.night_mode = false;
|
||||
override('night_mode.enable', stub.f); // automatically checks if called
|
||||
override('realm_logo.rerender', noop);
|
||||
dispatch(event);
|
||||
assert_same(page_params.night_mode, true);
|
||||
});
|
||||
|
||||
@@ -7,6 +7,8 @@ zrequire('XDate', 'xdate');
|
||||
zrequire('timerender');
|
||||
zrequire('Handlebars', 'handlebars');
|
||||
zrequire('util');
|
||||
zrequire('stream_color');
|
||||
zrequire('colorspace');
|
||||
|
||||
var ls_container = {};
|
||||
var noop = function () { return; };
|
||||
@@ -231,6 +233,8 @@ run_test('remove_old_drafts', () => {
|
||||
});
|
||||
|
||||
run_test('format_drafts', () => {
|
||||
drafts.remove_old_drafts = noop;
|
||||
|
||||
draft_1.updatedAt = new Date(1549958107000).getTime(); // 2/12/2019 07:55:07 AM (UTC+0)
|
||||
draft_2.updatedAt = new Date(1549958107000).setDate(-1);
|
||||
var draft_3 = {
|
||||
@@ -257,27 +261,14 @@ run_test('format_drafts', () => {
|
||||
|
||||
var expected = [
|
||||
{
|
||||
draft_id: 'id3',
|
||||
draft_id: 'id1',
|
||||
is_stream: true,
|
||||
stream: 'stream 2',
|
||||
stream: 'stream',
|
||||
stream_color: '#FFFFFF',
|
||||
dark_background: '',
|
||||
topic: 'topic',
|
||||
raw_content: 'Test Stream Message 2',
|
||||
time_stamp: 'Jan 21',
|
||||
},
|
||||
{
|
||||
draft_id: 'id4',
|
||||
is_stream: false,
|
||||
recipients: 'aaron',
|
||||
raw_content: 'Test Private Message 2',
|
||||
time_stamp: 'Jan 26',
|
||||
},
|
||||
{
|
||||
draft_id: 'id5',
|
||||
is_stream: false,
|
||||
recipients: 'aaron',
|
||||
raw_content: 'Test Private Message 3',
|
||||
time_stamp: 'Jan 29',
|
||||
raw_content: 'Test Stream Message',
|
||||
time_stamp: '7:55 AM',
|
||||
},
|
||||
{
|
||||
draft_id: 'id2',
|
||||
@@ -287,13 +278,28 @@ run_test('format_drafts', () => {
|
||||
time_stamp: 'Jan 30',
|
||||
},
|
||||
{
|
||||
draft_id: 'id1',
|
||||
draft_id: 'id5',
|
||||
is_stream: false,
|
||||
recipients: 'aaron',
|
||||
raw_content: 'Test Private Message 3',
|
||||
time_stamp: 'Jan 29',
|
||||
},
|
||||
{
|
||||
draft_id: 'id4',
|
||||
is_stream: false,
|
||||
recipients: 'aaron',
|
||||
raw_content: 'Test Private Message 2',
|
||||
time_stamp: 'Jan 26',
|
||||
},
|
||||
{
|
||||
draft_id: 'id3',
|
||||
is_stream: true,
|
||||
stream: 'stream',
|
||||
stream: 'stream 2',
|
||||
stream_color: '#FFFFFF',
|
||||
dark_background: '',
|
||||
topic: 'topic',
|
||||
raw_content: 'Test Stream Message',
|
||||
time_stamp: '7:55 AM',
|
||||
raw_content: 'Test Stream Message 2',
|
||||
time_stamp: 'Jan 21',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -302,10 +302,10 @@ run_test('marked', () => {
|
||||
expected: '<p><span aria-label="poop" class="emoji emoji-1f4a9" role="img" title="poop">:poop:</span></p>'},
|
||||
{input: '\u{1f6b2}',
|
||||
expected: '<p>\u{1f6b2}</p>' },
|
||||
{input: 'Silent mention: _@**Cordelia Lear**',
|
||||
expected: '<p>Silent mention: <span class="user-mention silent" data-user-id="101">@Cordelia Lear</span></p>'},
|
||||
{input: 'Silent mention: @_**Cordelia Lear**',
|
||||
expected: '<p>Silent mention: <span class="user-mention silent" data-user-id="101">Cordelia Lear</span></p>'},
|
||||
{input: '> Mention in quote: @**Cordelia Lear**\n\nMention outside quote: @**Cordelia Lear**',
|
||||
expected: '<blockquote>\n<p>Mention in quote: <span class="user-mention silent" data-user-id="101">@Cordelia Lear</span></p>\n</blockquote>\n<p>Mention outside quote: <span class="user-mention" data-user-id="101">@Cordelia Lear</span></p>'},
|
||||
expected: '<blockquote>\n<p>Mention in quote: <span class="user-mention silent" data-user-id="101">Cordelia Lear</span></p>\n</blockquote>\n<p>Mention outside quote: <span class="user-mention" data-user-id="101">@Cordelia Lear</span></p>'},
|
||||
// Test only those realm filters which don't return True for
|
||||
// `contains_backend_only_syntax()`. Those which return True
|
||||
// are tested separately.
|
||||
@@ -519,6 +519,19 @@ run_test('python_to_js_filter', () => {
|
||||
var actual_value = marked.InlineLexer.rules.zulip.realm_filters;
|
||||
var expected_value = [/\/aa\/g(?![\w])/gim, /\/aa\/g(?![\w])/g];
|
||||
assert.deepEqual(actual_value, expected_value);
|
||||
// Test case with multiple replacements.
|
||||
markdown.set_realm_filters([['#cf(?P<contest>[0-9]+)(?P<problem>[A-Z][0-9A-Z]*)', 'http://google.com']]);
|
||||
actual_value = marked.InlineLexer.rules.zulip.realm_filters;
|
||||
expected_value = [/#cf([0-9]+)([A-Z][0-9A-Z]*)(?![\w])/g];
|
||||
assert.deepEqual(actual_value, expected_value);
|
||||
// Test incorrect syntax.
|
||||
blueslip.set_test_data('error', 'python_to_js_filter: Invalid regular expression: /!@#@(!#&((!&(@#((?![\\w])/: Unterminated group');
|
||||
markdown.set_realm_filters([['!@#@(!#&((!&(@#(', 'http://google.com']]);
|
||||
actual_value = marked.InlineLexer.rules.zulip.realm_filters;
|
||||
expected_value = [];
|
||||
assert.deepEqual(actual_value, expected_value);
|
||||
assert.equal(blueslip.get_test_logs('error').length, 1);
|
||||
blueslip.clear_test_data();
|
||||
});
|
||||
|
||||
run_test('katex_throws_unexpected_exceptions', () => {
|
||||
@@ -526,6 +539,15 @@ run_test('katex_throws_unexpected_exceptions', () => {
|
||||
blueslip.set_test_data('error', 'Error: some-exception');
|
||||
var message = { raw_content: '$$a$$' };
|
||||
markdown.apply_markdown(message);
|
||||
assert(blueslip.get_test_logs('error').length, 1);
|
||||
assert.equal(blueslip.get_test_logs('error').length, 1);
|
||||
blueslip.clear_test_data();
|
||||
});
|
||||
|
||||
run_test('misc_helpers', () => {
|
||||
const elem = $('.user-mention');
|
||||
markdown.set_name_in_mention_element(elem, 'Aaron');
|
||||
assert.equal(elem.text(), '@Aaron');
|
||||
elem.addClass('silent');
|
||||
markdown.set_name_in_mention_element(elem, 'Aaron, but silent');
|
||||
assert.equal(elem.text(), 'Aaron, but silent');
|
||||
});
|
||||
|
||||
@@ -126,7 +126,7 @@ run_test('merge_message_groups', () => {
|
||||
assert.deepEqual(result.prepend_groups, []);
|
||||
assert.deepEqual(result.rerender_groups, []);
|
||||
assert.deepEqual(result.append_messages, []);
|
||||
assert.deepEqual(result.rerender_messages, []);
|
||||
assert.deepEqual(result.rerender_messages_next_same_sender, []);
|
||||
}());
|
||||
|
||||
(function test_append_message_same_subject() {
|
||||
@@ -151,7 +151,7 @@ run_test('merge_message_groups', () => {
|
||||
assert.deepEqual(result.prepend_groups, []);
|
||||
assert.deepEqual(result.rerender_groups, []);
|
||||
assert_message_list_equal(result.append_messages, [message2]);
|
||||
assert_message_list_equal(result.rerender_messages, [message1]);
|
||||
assert_message_list_equal(result.rerender_messages_next_same_sender, [message1]);
|
||||
}());
|
||||
|
||||
(function test_append_message_different_subject() {
|
||||
@@ -177,7 +177,7 @@ run_test('merge_message_groups', () => {
|
||||
assert.deepEqual(result.prepend_groups, []);
|
||||
assert.deepEqual(result.rerender_groups, []);
|
||||
assert.deepEqual(result.append_messages, []);
|
||||
assert.deepEqual(result.rerender_messages, []);
|
||||
assert.deepEqual(result.rerender_messages_next_same_sender, []);
|
||||
}());
|
||||
|
||||
(function test_append_message_different_subject_and_days() {
|
||||
@@ -203,7 +203,7 @@ run_test('merge_message_groups', () => {
|
||||
assert.deepEqual(result.prepend_groups, []);
|
||||
assert.deepEqual(result.rerender_groups, []);
|
||||
assert.deepEqual(result.append_messages, []);
|
||||
assert.deepEqual(result.rerender_messages, []);
|
||||
assert.deepEqual(result.rerender_messages_next_same_sender, []);
|
||||
assert.equal(
|
||||
message_group2.group_date_divider_html,
|
||||
'900000000 - 1000000');
|
||||
@@ -229,7 +229,7 @@ run_test('merge_message_groups', () => {
|
||||
assert.deepEqual(result.prepend_groups, []);
|
||||
assert.deepEqual(result.rerender_groups, []);
|
||||
assert.deepEqual(result.append_messages, [message2]);
|
||||
assert.deepEqual(result.rerender_messages, [message1]);
|
||||
assert.deepEqual(result.rerender_messages_next_same_sender, [message1]);
|
||||
assert(list._message_groups[0].message_containers[1].want_date_divider);
|
||||
}());
|
||||
|
||||
@@ -256,7 +256,7 @@ run_test('merge_message_groups', () => {
|
||||
assert.deepEqual(result.prepend_groups, []);
|
||||
assert.deepEqual(result.rerender_groups, []);
|
||||
assert.deepEqual(result.append_messages, []);
|
||||
assert.deepEqual(result.rerender_messages, []);
|
||||
assert.deepEqual(result.rerender_messages_next_same_sender, []);
|
||||
}());
|
||||
|
||||
(function test_append_message_same_subject_me_message() {
|
||||
@@ -282,7 +282,7 @@ run_test('merge_message_groups', () => {
|
||||
assert.deepEqual(result.prepend_groups, []);
|
||||
assert.deepEqual(result.rerender_groups, []);
|
||||
assert_message_list_equal(result.append_messages, [message2]);
|
||||
assert_message_list_equal(result.rerender_messages, [message1]);
|
||||
assert_message_list_equal(result.rerender_messages_next_same_sender, [message1]);
|
||||
}());
|
||||
|
||||
|
||||
@@ -309,7 +309,7 @@ run_test('merge_message_groups', () => {
|
||||
assert_message_groups_list_equal(result.rerender_groups,
|
||||
[build_message_group([message2, message1])]);
|
||||
assert.deepEqual(result.append_messages, []);
|
||||
assert.deepEqual(result.rerender_messages, []);
|
||||
assert.deepEqual(result.rerender_messages_next_same_sender, []);
|
||||
}());
|
||||
|
||||
(function test_prepend_message_different_subject() {
|
||||
@@ -334,7 +334,7 @@ run_test('merge_message_groups', () => {
|
||||
assert_message_groups_list_equal(result.prepend_groups, [message_group2]);
|
||||
assert.deepEqual(result.rerender_groups, []);
|
||||
assert.deepEqual(result.append_messages, []);
|
||||
assert.deepEqual(result.rerender_messages, []);
|
||||
assert.deepEqual(result.rerender_messages_next_same_sender, []);
|
||||
}());
|
||||
|
||||
(function test_prepend_message_different_subject_and_day() {
|
||||
@@ -364,7 +364,7 @@ run_test('merge_message_groups', () => {
|
||||
assert_message_groups_list_equal(result.prepend_groups, [message_group2]);
|
||||
assert.deepEqual(result.rerender_groups, [message_group1]);
|
||||
assert.deepEqual(result.append_messages, []);
|
||||
assert.deepEqual(result.rerender_messages, []);
|
||||
assert.deepEqual(result.rerender_messages_next_same_sender, []);
|
||||
}());
|
||||
|
||||
(function test_prepend_message_different_day() {
|
||||
@@ -393,7 +393,7 @@ run_test('merge_message_groups', () => {
|
||||
assert.deepEqual(result.prepend_groups, []);
|
||||
assert_message_groups_list_equal(result.rerender_groups, [message_group2]);
|
||||
assert.deepEqual(result.append_messages, []);
|
||||
assert.deepEqual(result.rerender_messages, []);
|
||||
assert.deepEqual(result.rerender_messages_next_same_sender, []);
|
||||
}());
|
||||
|
||||
(function test_prepend_message_historical() {
|
||||
@@ -419,11 +419,15 @@ run_test('merge_message_groups', () => {
|
||||
assert_message_groups_list_equal(result.prepend_groups, [message_group2]);
|
||||
assert.deepEqual(result.rerender_groups, []);
|
||||
assert.deepEqual(result.append_messages, []);
|
||||
assert.deepEqual(result.rerender_messages, []);
|
||||
assert.deepEqual(result.rerender_messages_next_same_sender, []);
|
||||
}());
|
||||
|
||||
});
|
||||
|
||||
// TODO: Add a test suite for rerender_messages_next_same_sender() that includes cases
|
||||
// where new messages added via local echo have a different date from
|
||||
// the older messages.
|
||||
|
||||
run_test('render_windows', () => {
|
||||
// We only render up to 400 messages at a time in our message list,
|
||||
// and we only change the window (which is a range, really, with
|
||||
|
||||
@@ -184,6 +184,12 @@ run_test('update_booleans', () => {
|
||||
assert.equal(message.unread, true);
|
||||
});
|
||||
|
||||
run_test('each', () => {
|
||||
message_store.each((message) => {
|
||||
assert(message.alerted !== undefined);
|
||||
});
|
||||
});
|
||||
|
||||
run_test('message_id_change', () => {
|
||||
var message = {
|
||||
sender_email: 'me@example.com',
|
||||
|
||||
@@ -7,6 +7,9 @@ zrequire('stream_data');
|
||||
zrequire('util');
|
||||
zrequire('Filter', 'js/filter');
|
||||
set_global('i18n', global.stub_i18n);
|
||||
set_global('page_params', {
|
||||
stop_words: ['what', 'about'],
|
||||
});
|
||||
|
||||
zrequire('narrow');
|
||||
|
||||
@@ -153,9 +156,36 @@ run_test('show_empty_narrow_message', () => {
|
||||
narrow.show_empty_narrow_message();
|
||||
assert($('#non_existing_user').visible());
|
||||
|
||||
var display = $("#empty_search_stop_words_string");
|
||||
|
||||
var items = [];
|
||||
display.append = (html) => {
|
||||
items.push(html);
|
||||
};
|
||||
|
||||
set_filter([['search', 'grail']]);
|
||||
narrow.show_empty_narrow_message();
|
||||
assert($('#empty_search_narrow_message').visible());
|
||||
|
||||
assert.equal(items.length, 2);
|
||||
assert.equal(items[0], ' ');
|
||||
assert.equal(items[1].text(), 'grail');
|
||||
|
||||
items = [];
|
||||
display.append = (html) => {
|
||||
if (html.text) {
|
||||
items.push(html.selector + html.text());
|
||||
}
|
||||
};
|
||||
|
||||
set_filter([['search', 'what about grail']]);
|
||||
narrow.show_empty_narrow_message();
|
||||
assert($('#empty_search_narrow_message').visible());
|
||||
|
||||
assert.equal(items.length, 3);
|
||||
assert.equal(items[0], '<del>what');
|
||||
assert.equal(items[1], '<del>about');
|
||||
assert.equal(items[2], '<span>grail');
|
||||
});
|
||||
|
||||
run_test('narrow_to_compose_target', () => {
|
||||
|
||||
@@ -833,7 +833,7 @@ run_test('initialize', () => {
|
||||
assert(people.is_my_user_id(42));
|
||||
|
||||
var fetched_retiree = people.get_person_from_user_id(15);
|
||||
assert(fetched_retiree.full_name, 'Retiree');
|
||||
assert.equal(fetched_retiree.full_name, 'Retiree');
|
||||
|
||||
assert.equal(global.page_params.realm_users, undefined);
|
||||
assert.equal(global.page_params.cross_realm_bots, undefined);
|
||||
|
||||
@@ -4,6 +4,9 @@ set_global('narrow_state', {});
|
||||
set_global('resize', {
|
||||
resize_stream_filters_container: function () {},
|
||||
});
|
||||
set_global('ui', {
|
||||
set_up_scrollbar: function () {},
|
||||
});
|
||||
set_global('stream_popover', {
|
||||
hide_topic_popover: function () {},
|
||||
});
|
||||
@@ -14,6 +17,9 @@ set_global('popovers', {
|
||||
hide_all: function () {},
|
||||
});
|
||||
|
||||
zrequire('user_status');
|
||||
zrequire('presence');
|
||||
zrequire('buddy_data');
|
||||
zrequire('hash_util');
|
||||
zrequire('Handlebars', 'handlebars');
|
||||
zrequire('templates');
|
||||
@@ -48,7 +54,7 @@ run_test('get_conversation_li', () => {
|
||||
|
||||
run_test('close', () => {
|
||||
var collapsed;
|
||||
$('ul.expanded_private_messages').remove = function () {
|
||||
$('#private-container').remove = function () {
|
||||
collapsed = true;
|
||||
};
|
||||
pm_list.close();
|
||||
@@ -86,6 +92,9 @@ run_test('build_private_messages_list', () => {
|
||||
is_zero: false,
|
||||
zoom_out_hide: false,
|
||||
url: '#narrow/pm-with/101,102-group',
|
||||
user_circle_class: 'user_circle_fraction',
|
||||
fraction_present: false,
|
||||
is_group: true,
|
||||
},
|
||||
],
|
||||
zoom_class: 'zoomed-out',
|
||||
@@ -118,7 +127,7 @@ run_test('build_private_messages_list', () => {
|
||||
|
||||
run_test('expand_and_update_private_messages', () => {
|
||||
var collapsed;
|
||||
$('ul.expanded_private_messages').remove = function () {
|
||||
$('#private-container').remove = function () {
|
||||
collapsed = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ run_test('sender_hover', () => {
|
||||
|
||||
templates.render = function (fn, opts) {
|
||||
switch (fn) {
|
||||
case 'user_info_popover':
|
||||
case 'no_arrow_popover':
|
||||
assert.deepEqual(opts, {
|
||||
class: 'message-info-popover',
|
||||
});
|
||||
@@ -157,7 +157,7 @@ run_test('sender_hover', () => {
|
||||
user_id: 42,
|
||||
user_time: undefined,
|
||||
user_type: i18n.t('Member'),
|
||||
type: 'offline',
|
||||
user_circle_class: 'user_circle_empty',
|
||||
user_last_seen_time_status: 'translated: More than 2 weeks ago',
|
||||
pm_with_uri: '#narrow/pm-with/42-alice',
|
||||
sent_by_uri: '#narrow/sender/42-alice',
|
||||
|
||||
@@ -73,5 +73,5 @@ run_test('create_pills', () => {
|
||||
|
||||
var pills = search_pill.create_pills({});
|
||||
assert(input_pill_create_called);
|
||||
assert(pills, {dummy: 'dummy'});
|
||||
assert.deepEqual(pills, {dummy: 'dummy'});
|
||||
});
|
||||
|
||||
@@ -9,6 +9,7 @@ global.stub_out_jquery();
|
||||
zrequire('message_store');
|
||||
zrequire('server_events_dispatch');
|
||||
zrequire('server_events');
|
||||
zrequire('sent_messages');
|
||||
|
||||
set_global('blueslip', global.make_zblueslip());
|
||||
set_global('channel', {});
|
||||
|
||||
@@ -57,6 +57,7 @@ const _ui_report = {
|
||||
|
||||
const _realm_logo = {
|
||||
build_realm_logo_widget: noop,
|
||||
build_realm_night_logo_widget: noop,
|
||||
};
|
||||
|
||||
set_global('channel', _channel);
|
||||
|
||||
@@ -302,7 +302,7 @@ run_test('populate_user_groups', () => {
|
||||
assert(user_groups_list_append_called);
|
||||
assert(get_person_from_user_id_called);
|
||||
assert(input_typeahead_called);
|
||||
assert(blueslip.get_test_logs('warn').length, 1);
|
||||
assert.equal(blueslip.get_test_logs('warn').length, 1);
|
||||
blueslip.clear_test_data();
|
||||
test_create_item(create_item_handler);
|
||||
|
||||
|
||||
@@ -281,9 +281,15 @@ run_test('subscribers', () => {
|
||||
run_test('is_active', () => {
|
||||
stream_data.clear_subscriptions();
|
||||
|
||||
var sub = {name: 'pets', subscribed: false, stream_id: 1};
|
||||
var sub;
|
||||
|
||||
sub = {name: 'pets', subscribed: false, stream_id: 111};
|
||||
stream_data.add_sub('pets', sub);
|
||||
|
||||
assert(stream_data.is_active(sub));
|
||||
|
||||
stream_data.set_filter_out_inactives(true);
|
||||
|
||||
assert(!stream_data.is_active(sub));
|
||||
|
||||
stream_data.subscribe_myself(sub);
|
||||
@@ -639,6 +645,7 @@ run_test('initialize', () => {
|
||||
initialize();
|
||||
page_params.realm_notifications_stream_id = -1;
|
||||
stream_data.initialize();
|
||||
assert(!stream_data.is_filtering_inactives());
|
||||
|
||||
const stream_names = stream_data.get_streams_for_admin().map(elem => elem.name);
|
||||
assert(stream_names.indexOf('subscriptions') !== -1);
|
||||
@@ -667,6 +674,34 @@ run_test('initialize', () => {
|
||||
assert.equal(page_params.notifications_stream, "foo");
|
||||
});
|
||||
|
||||
run_test('filter inactives', () => {
|
||||
page_params.unsubscribed = [];
|
||||
page_params.never_subscribed = [];
|
||||
page_params.subscriptions = [];
|
||||
|
||||
stream_data.initialize();
|
||||
assert(!stream_data.is_filtering_inactives());
|
||||
|
||||
page_params.unsubscribed = [];
|
||||
page_params.never_subscribed = [];
|
||||
page_params.subscriptions = [];
|
||||
|
||||
_.times(30, function (i) {
|
||||
var name = 'random' + i.toString();
|
||||
var stream_id = 100 + i;
|
||||
|
||||
var sub = {
|
||||
name: name,
|
||||
subscribed: true,
|
||||
newly_subscribed: false,
|
||||
stream_id: stream_id,
|
||||
};
|
||||
stream_data.add_sub(name, sub);
|
||||
});
|
||||
stream_data.initialize();
|
||||
assert(stream_data.is_filtering_inactives());
|
||||
});
|
||||
|
||||
run_test('get_newbie_stream', () => {
|
||||
var newbie = {
|
||||
name: 'newbie',
|
||||
|
||||
@@ -8,6 +8,7 @@ const noop = () => {};
|
||||
|
||||
set_global('resize', {
|
||||
resize_page_components: noop,
|
||||
resize_stream_filters_container: noop,
|
||||
});
|
||||
|
||||
set_global('popovers', {});
|
||||
@@ -38,31 +39,33 @@ function simulate_search_expanded() {
|
||||
// The way we check if the search widget is expanded
|
||||
// is kind of awkward.
|
||||
|
||||
$('#stream-filters-container .input-append.notdisplayed').length = 0;
|
||||
$('.stream_search_section.notdisplayed').length = 0;
|
||||
}
|
||||
|
||||
function simulate_search_collapsed() {
|
||||
$('#stream-filters-container .input-append.notdisplayed').length = 1;
|
||||
$('.stream_search_section.notdisplayed').length = 1;
|
||||
}
|
||||
|
||||
function toggle_filter() {
|
||||
stream_list.toggle_filter_displayed({preventDefault: noop});
|
||||
}
|
||||
|
||||
function clear_search_input() {
|
||||
stream_list.clear_search({stopPropagation: noop});
|
||||
}
|
||||
|
||||
run_test('basics', () => {
|
||||
var cursor_helper;
|
||||
const input = $('.stream-list-filter');
|
||||
const header = $.create('header stub');
|
||||
|
||||
input.parent = () => header;
|
||||
const section = $('.stream_search_section');
|
||||
|
||||
expand_sidebar();
|
||||
header.addClass('notdisplayed');
|
||||
section.addClass('notdisplayed');
|
||||
|
||||
cursor_helper = make_cursor_helper();
|
||||
|
||||
function verify_expanded() {
|
||||
assert(!header.hasClass('notdisplayed'));
|
||||
assert(!section.hasClass('notdisplayed'));
|
||||
simulate_search_expanded();
|
||||
}
|
||||
|
||||
@@ -77,7 +80,7 @@ run_test('basics', () => {
|
||||
}
|
||||
|
||||
function verify_collapsed() {
|
||||
assert(header.hasClass('notdisplayed'));
|
||||
assert(section.hasClass('notdisplayed'));
|
||||
assert(!input.is_focused());
|
||||
assert(!stream_list.searching());
|
||||
simulate_search_collapsed();
|
||||
@@ -130,7 +133,7 @@ run_test('basics', () => {
|
||||
verify_focused();
|
||||
|
||||
// Clear an empty search.
|
||||
stream_list.clear_search();
|
||||
clear_search_input();
|
||||
verify_collapsed();
|
||||
|
||||
// Expand the widget.
|
||||
@@ -140,7 +143,7 @@ run_test('basics', () => {
|
||||
// Clear a non-empty search.
|
||||
input.val('foo');
|
||||
verify_list_updated(() => {
|
||||
stream_list.clear_search();
|
||||
clear_search_input();
|
||||
});
|
||||
verify_expanded();
|
||||
|
||||
|
||||
@@ -294,9 +294,6 @@ run_test('admin_invites_list', () => {
|
||||
|
||||
var span = $(html).find(".email:first");
|
||||
assert.equal(span.text(), "alice@zulip.com");
|
||||
|
||||
var icon = $(html).find(".fa-bolt");
|
||||
assert.equal(icon.attr('title'), "translated: Invited as administrator");
|
||||
});
|
||||
|
||||
run_test('admin_tab', () => {
|
||||
@@ -646,8 +643,6 @@ run_test('draft_table_body', () => {
|
||||
assert.equal(row_1.find(".stream_label").css("background"), "rgb(255, 0, 0)");
|
||||
assert.equal(row_1.find(".stream_topic").text().trim(), "tests");
|
||||
assert(!row_1.find(".message_row").hasClass("private-message"));
|
||||
assert.equal(row_1.find(".messagebox").css("box-shadow"),
|
||||
"inset 2px 0px 0px 0px #FF0000, -1px 0px 0px 0px #FF0000");
|
||||
assert.equal(row_1.find(".message_content").text().trim(), "Public draft");
|
||||
|
||||
var row_2 = $(html).find(".draft-row[data-draft-id='2']");
|
||||
@@ -1052,6 +1047,18 @@ run_test('reminder_popover_content', () => {
|
||||
assert.equal(link.text().trim(), 'translated: Select date and time');
|
||||
});
|
||||
|
||||
run_test('revoke_invite_modal', () => {
|
||||
var args = {
|
||||
is_multiuse: false,
|
||||
email: "iago@zulip.com",
|
||||
};
|
||||
|
||||
var html = "<div>";
|
||||
html += render('revoke-invite-modal', args);
|
||||
html += "</div>";
|
||||
assert.equal($(html).find("p strong").text(), "iago@zulip.com");
|
||||
});
|
||||
|
||||
run_test('settings_tab', () => {
|
||||
var page_param_checkbox_options = {
|
||||
enable_stream_desktop_notifications: true,
|
||||
@@ -1415,19 +1422,16 @@ run_test('user_group_info_popover_content', () => {
|
||||
group_description: 'groupDescription',
|
||||
members: [
|
||||
{
|
||||
presence_status: 'active',
|
||||
full_name: 'Active Alice',
|
||||
user_last_seen_time_status: 'time',
|
||||
is_bot: false,
|
||||
},
|
||||
{
|
||||
presence_status: 'offline',
|
||||
full_name: 'Bot Bob',
|
||||
user_last_seen_time_status: 'time',
|
||||
is_bot: true,
|
||||
},
|
||||
{
|
||||
presence_status: 'offline',
|
||||
full_name: 'Inactive Imogen',
|
||||
user_last_seen_time_status: 'time',
|
||||
is_bot: false,
|
||||
@@ -1438,8 +1442,6 @@ run_test('user_group_info_popover_content', () => {
|
||||
var html = render('user_group_info_popover_content', args);
|
||||
|
||||
var allUsers = $(html).find("li");
|
||||
assert.equal(allUsers[0].classList.contains("user_active"), true);
|
||||
assert.equal(allUsers[2].classList.contains("user_offline"), true);
|
||||
assert.equal($(allUsers[0]).text().trim(), 'Active Alice');
|
||||
assert.equal($(allUsers[1]).text().trim(), 'Bot Bob');
|
||||
assert.equal($(allUsers[2]).text().trim(), 'Inactive Imogen');
|
||||
@@ -1448,8 +1450,8 @@ run_test('user_group_info_popover_content', () => {
|
||||
assert.equal($(html).find('.group-description').text().trim(), 'groupDescription');
|
||||
});
|
||||
|
||||
run_test('user_info_popover', () => {
|
||||
var html = render('user_info_popover', {class: 'message-info-popover'});
|
||||
run_test('no_arrow_popover', () => {
|
||||
var html = render('no_arrow_popover', {class: 'message-info-popover'});
|
||||
|
||||
$(html).hasClass('popover message-info-popover');
|
||||
});
|
||||
|
||||
@@ -50,14 +50,14 @@ run_test('user_groups', () => {
|
||||
|
||||
blueslip.set_test_data('error', 'Unknown group_id in get_user_group_from_id: ' + all.id);
|
||||
assert.equal(user_groups.get_user_group_from_id(all.id), undefined);
|
||||
assert(blueslip.get_test_logs('error').length, 1);
|
||||
assert.equal(blueslip.get_test_logs('error').length, 1);
|
||||
blueslip.clear_test_data();
|
||||
|
||||
user_groups.remove(students);
|
||||
|
||||
blueslip.set_test_data('error', 'Unknown group_id in get_user_group_from_id: ' + students.id);
|
||||
assert.equal(user_groups.get_user_group_from_id(students.id), undefined);
|
||||
assert(blueslip.get_test_logs('error').length, 1);
|
||||
assert.equal(blueslip.get_test_logs('error').length, 1);
|
||||
blueslip.clear_test_data();
|
||||
|
||||
assert.equal(user_groups.get_user_group_from_name(all.name), undefined);
|
||||
@@ -92,6 +92,6 @@ run_test('user_groups', () => {
|
||||
|
||||
blueslip.set_test_data('error', 'Could not find user group with ID -1');
|
||||
assert.equal(user_groups.is_member_of(-1, 15), false);
|
||||
assert(blueslip.get_test_logs('error').length, 1);
|
||||
assert.equal(blueslip.get_test_logs('error').length, 1);
|
||||
blueslip.clear_test_data();
|
||||
});
|
||||
|
||||
@@ -110,7 +110,7 @@ run_test('robust_uri_decode', () => {
|
||||
try {
|
||||
util.robust_uri_decode('%E0%A4%A');
|
||||
} catch (e) {
|
||||
assert(e, 'foo');
|
||||
assert.equal(e, 'foo');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -43,9 +43,9 @@
|
||||
"string.prototype.startswith": "0.2.0",
|
||||
"style-loader": "0.21.0",
|
||||
"to-markdown": "3.1.0",
|
||||
"ts-loader": "4.3.0",
|
||||
"ts-node": "3.3.0",
|
||||
"typescript": "2.8.3",
|
||||
"ts-loader": "5.3.3",
|
||||
"ts-node": "8.0.2",
|
||||
"typescript": "3.3.1",
|
||||
"underscore": "1.9.0",
|
||||
"webfonts-generator": "0.4.0",
|
||||
"webpack": "4.8.3",
|
||||
@@ -69,7 +69,7 @@
|
||||
"stylelint": "9.3.0",
|
||||
"svgo": "1.0.5",
|
||||
"swagger-parser": "3.4.1",
|
||||
"tslint": "5.10.0",
|
||||
"tslint": "5.12.1",
|
||||
"webpack-dev-server": "3.1.4",
|
||||
"xmlhttprequest": "1.8.0"
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<% else -%>
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
<% end -%>
|
||||
@@ -11,8 +12,10 @@ include /etc/nginx/zulip-include/upstreams;
|
||||
server {
|
||||
<% if @nginx_http_only != '' -%>
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
<% else -%>
|
||||
listen 443;
|
||||
listen [::]:443;
|
||||
|
||||
ssl on;
|
||||
ssl_certificate <%= @ssl_dir %>/certs/zulip.combined-chain.crt;
|
||||
|
||||
@@ -7,6 +7,7 @@ chmod-socket=700
|
||||
chown-socket=zulip:zulip
|
||||
processes=<%= @uwsgi_processes %>
|
||||
harakiri=20
|
||||
buffer-size=8192
|
||||
post-buffering=4096
|
||||
env= LANG=en_US.UTF-8
|
||||
uid=zulip
|
||||
|
||||
@@ -48,8 +48,6 @@ import logging
|
||||
import logging.handlers
|
||||
import subprocess
|
||||
|
||||
import sys
|
||||
|
||||
import boto.utils
|
||||
import netifaces
|
||||
if False:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# and requirements/prod.txt.
|
||||
# See requirements/README.md for more detail.
|
||||
# Django itself
|
||||
Django==1.11.18
|
||||
Django==1.11.20
|
||||
|
||||
# needed for mypy TypedDict
|
||||
mypy_extensions==0.4.1
|
||||
@@ -78,6 +78,9 @@ httplib2==0.12.0
|
||||
# Needed for hipchat import
|
||||
hypchat==0.21
|
||||
|
||||
# For doing highly usable Python profiling
|
||||
line_profiler==2.1.2
|
||||
|
||||
# Needed for inlining the CSS in emails
|
||||
premailer==3.2.0
|
||||
|
||||
@@ -175,8 +178,8 @@ pyoembed==0.1.2
|
||||
# these tightly, including fetching content not included in the normal
|
||||
# release tarballs (which is a bug). So we need to pin it makes sense
|
||||
# to pin a version from Git rather than a release.
|
||||
-e "git+https://github.com/zulip/python-zulip-api.git@0.5.8#egg=zulip==0.5.8_git&subdirectory=zulip"
|
||||
-e "git+https://github.com/zulip/python-zulip-api.git@0.5.8#egg=zulip_bots==0.5.8+git&subdirectory=zulip_bots"
|
||||
-e "git+https://github.com/zulip/python-zulip-api.git@0.5.9#egg=zulip==0.5.9_git&subdirectory=zulip"
|
||||
-e "git+https://github.com/zulip/python-zulip-api.git@0.5.9#egg=zulip_bots==0.5.9+git&subdirectory=zulip_bots"
|
||||
|
||||
# Used for Hesiod lookups, etc.
|
||||
py3dns==3.2.0
|
||||
|
||||
@@ -13,8 +13,8 @@ git+https://github.com/zulip/django-bitfield@0d2b15cdb5af5ddec88d41cac19c0f2ce1b
|
||||
git+https://github.com/zulip/libthumbor.git@60ed2431c07686a12f2770b2d852c5650f3ccfc6#egg=libthumbor==1.3.2zulip
|
||||
git+https://github.com/zulip/talon.git@7d8bdc4dbcfcc5a73298747293b99fe53da55315#egg=talon==1.2.10.zulip1
|
||||
git+https://github.com/zulip/ultrajson@70ac02bec#egg=ujson==1.35+git
|
||||
git+https://github.com/zulip/python-zulip-api.git@0.5.8#egg=zulip==0.5.8_git&subdirectory=zulip
|
||||
git+https://github.com/zulip/python-zulip-api.git@0.5.8#egg=zulip_bots==0.5.8+git&subdirectory=zulip_bots
|
||||
git+https://github.com/zulip/python-zulip-api.git@0.5.9#egg=zulip==0.5.9_git&subdirectory=zulip
|
||||
git+https://github.com/zulip/python-zulip-api.git@0.5.9#egg=zulip_bots==0.5.9+git&subdirectory=zulip_bots
|
||||
alabaster==0.7.12
|
||||
apns2==0.4.1
|
||||
argon2-cffi==19.1.0
|
||||
@@ -56,7 +56,7 @@ django-sendfile==0.3.11
|
||||
django-statsd-mozilla==0.4.0
|
||||
django-two-factor-auth==1.8.0
|
||||
django-webpack-loader==0.6.0
|
||||
django==1.11.18
|
||||
django==1.11.20
|
||||
docker-pycreds==0.4.0 # via docker
|
||||
docker==3.7.0 # via moto
|
||||
docopt==0.6.2
|
||||
@@ -90,6 +90,7 @@ jinja2==2.10
|
||||
jmespath==0.9.3 # via boto3, botocore
|
||||
jsondiff==1.1.1 # via moto
|
||||
jsonpickle==1.1 # via aws-xray-sdk, python-digitalocean
|
||||
line_profiler==2.1.2
|
||||
lxml==4.3.0
|
||||
markdown-include==0.5.1
|
||||
markdown==3.0.1
|
||||
|
||||
@@ -13,8 +13,8 @@ git+https://github.com/zulip/django-bitfield@0d2b15cdb5af5ddec88d41cac19c0f2ce1b
|
||||
git+https://github.com/zulip/libthumbor.git@60ed2431c07686a12f2770b2d852c5650f3ccfc6#egg=libthumbor==1.3.2zulip
|
||||
git+https://github.com/zulip/talon.git@7d8bdc4dbcfcc5a73298747293b99fe53da55315#egg=talon==1.2.10.zulip1
|
||||
git+https://github.com/zulip/ultrajson@70ac02bec#egg=ujson==1.35+git
|
||||
git+https://github.com/zulip/python-zulip-api.git@0.5.8#egg=zulip==0.5.8_git&subdirectory=zulip
|
||||
git+https://github.com/zulip/python-zulip-api.git@0.5.8#egg=zulip_bots==0.5.8+git&subdirectory=zulip_bots
|
||||
git+https://github.com/zulip/python-zulip-api.git@0.5.9#egg=zulip==0.5.9_git&subdirectory=zulip
|
||||
git+https://github.com/zulip/python-zulip-api.git@0.5.9#egg=zulip_bots==0.5.9+git&subdirectory=zulip_bots
|
||||
apns2==0.4.1
|
||||
argon2-cffi==19.1.0
|
||||
asn1crypto==0.24.0 # via cryptography
|
||||
@@ -45,7 +45,7 @@ django-sendfile==0.3.11
|
||||
django-statsd-mozilla==0.4.0
|
||||
django-two-factor-auth==1.8.0
|
||||
django-webpack-loader==0.6.0
|
||||
django==1.11.18
|
||||
django==1.11.20
|
||||
docopt==0.6.2
|
||||
gitdb==0.6.4
|
||||
google-api-python-client==1.7.4
|
||||
@@ -64,6 +64,7 @@ ipython-genutils==0.2.0 # via traitlets
|
||||
ipython==6.5.0
|
||||
jedi==0.13.2 # via ipython
|
||||
jinja2==2.10
|
||||
line_profiler==2.1.2
|
||||
lxml==4.3.0
|
||||
markdown-include==0.5.1
|
||||
markdown==3.0.1
|
||||
|
||||
@@ -218,6 +218,16 @@ def try_to_copy_venv(venv_path, new_packages):
|
||||
# virtualenv-clone isn't working, so just make a new venv
|
||||
return False
|
||||
|
||||
# virtualenv-clone, unfortunately, copies the success stamp,
|
||||
# which means if the upcoming `pip install` phase were to
|
||||
# fail, we'd end up with a broken half-provisioned virtualenv
|
||||
# that's incorrectly tagged as properly provisioned. The
|
||||
# right fix is to use
|
||||
# https://github.com/edwardgeorge/virtualenv-clone/pull/38,
|
||||
# but this rm is almost as good.
|
||||
success_stamp_path = os.path.join(venv_path, 'success-stamp')
|
||||
run(["sudo", "rm", "-f", success_stamp_path])
|
||||
|
||||
run(["sudo", "chown", "-R",
|
||||
"{}:{}".format(os.getuid(), os.getgid()), venv_path])
|
||||
source_log = get_logfile_name(source_venv_path)
|
||||
|
||||
@@ -99,7 +99,7 @@ chmod a+x "$CERTBOT_PATH"
|
||||
# an annoying prompt we stifle with --no-eff-email.
|
||||
"$CERTBOT_PATH" certonly "${method_args[@]}" \
|
||||
"${HOSTNAMES[@]}" -m "$EMAIL" \
|
||||
$agree_tos --force-renewal \
|
||||
$agree_tos \
|
||||
"${deploy_hook[@]}" \
|
||||
--force-interactive --no-eff-email
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 19 KiB |
1
static/images/integrations/logos/beeminder.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><path fill="#ffcc2a" d="M81.103 59.577c-3.088 0-6.275-.973-8.975-2.738l-15.1-10.295a3.743 3.743 0 0 1-1.635-3.097c0-1.24.61-2.4 1.635-3.098l14.961-10.2c2.807-1.841 6.022-2.832 9.113-2.832 8.03 0 12.822 6.031 12.822 16.131 0 10.101-4.792 16.131-12.822 16.131m-61.674-.002c-8.03 0-12.825-6.03-12.825-16.131 0-10.1 4.793-16.131 12.822-16.131 3.087 0 6.276.972 8.977 2.737l15.097 10.295a3.748 3.748 0 0 1 .002 6.195l-14.96 10.201c-2.812 1.841-6.027 2.832-9.115 2.832m30.837-18.429a3.743 3.743 0 0 1-2.111-.651l-14.211-9.69a3.75 3.75 0 0 1-1.542-3.936 19.169 19.169 0 0 1 2.421-5.856 31.072 31.072 0 0 0-1.962-2.925 6.824 6.824 0 0 1-1.313-5.097 6.811 6.811 0 0 1 2.677-4.528 6.79 6.79 0 0 1 4.126-1.382 6.905 6.905 0 0 1 5.497 2.743 45.76 45.76 0 0 1 2.087 3.008 17.81 17.81 0 0 1 9.418.216 45.581 45.581 0 0 1 2.225-3.227A6.911 6.911 0 0 1 63.07 7.08c1.501 0 2.927.475 4.128 1.38a6.813 6.813 0 0 1 2.677 4.533 6.842 6.842 0 0 1-1.312 5.095 29.967 29.967 0 0 0-2.392 3.683 18.979 18.979 0 0 1 1.96 5.102 3.758 3.758 0 0 1-1.542 3.931l-14.212 9.69a3.757 3.757 0 0 1-2.113.651m-.013 51.777A3.746 3.746 0 0 1 47.788 92L36.72 82.364c-5.566-4.487-9.113-11.531-9.732-19.343a3.747 3.747 0 0 1 1.877-3.552c.358-.205.717-.415 1.068-.643l18.218-12.423a3.744 3.744 0 0 1 4.226 0l18.362 12.516c.266.176.6.368.932.558a3.744 3.744 0 0 1 1.862 3.547c-.62 7.802-4.17 14.846-9.738 19.338l-11.083 9.641a3.748 3.748 0 0 1-2.461.92"/><path fill="#4d4c4e" d="M81.103 55.827c-2.368 0-4.856-.773-6.923-2.126L59.144 43.446l14.957-10.2c2.146-1.406 4.633-2.181 7.002-2.181 5.852 0 9.072 4.397 9.072 12.381 0 7.981-3.22 12.381-9.072 12.381M61.391 79.484l-10.316 8.973-.823.713-.817-.713-10.308-8.971c-4.831-3.867-7.865-10.025-8.401-16.762.426-.245.848-.493 1.261-.762l6.177-4.211 12.101-8.253 12.11 8.253 6.255 4.262c.377.251.776.481 1.168.711-.537 6.737-3.578 12.89-8.406 16.76M19.426 55.827c-5.847 0-9.072-4.4-9.072-12.381 0-7.983 3.225-12.381 9.072-12.381 2.368 0 4.856.775 6.926 2.127l15.04 10.253-14.961 10.201c-2.148 1.406-4.633 2.18-7.001 2.18h-.003zm17.047-44.371a3.125 3.125 0 0 1 4.375.62 39.868 39.868 0 0 1 3.407 5.315 14.087 14.087 0 0 1 12.721.366 40.178 40.178 0 0 1 3.593-5.681 3.121 3.121 0 0 1 2.5-1.247 3.122 3.122 0 0 1 2.494 5.004c-1.74 2.313-2.907 4.395-3.696 6.176a15.35 15.35 0 0 1 2.605 5.696l-14.211 9.69-14.211-9.69a15.365 15.365 0 0 1 3.17-6.401c-.775-1.618-1.848-3.455-3.37-5.471a3.129 3.129 0 0 1 .62-4.377m44.631 12.108c-3.161 0-6.411.845-9.341 2.381a22.758 22.758 0 0 0-1.322-4.008c.343-.527.72-1.062 1.122-1.6 3.521-4.677 2.576-11.355-2.103-14.875a10.556 10.556 0 0 0-6.387-2.135c-3.32 0-6.496 1.585-8.493 4.238a58.88 58.88 0 0 0-.915 1.256 21.37 21.37 0 0 0-3.398-.271c-.871 0-1.736.051-2.59.153-.271-.381-.55-.762-.832-1.138a10.673 10.673 0 0 0-8.491-4.238c-2.323 0-4.533.74-6.388 2.138-4.678 3.518-5.622 10.193-2.101 14.873.206.276.407.55.597.823a23.056 23.056 0 0 0-1.69 4.772c-2.911-1.531-6.161-2.371-9.342-2.371-7.643 0-16.572 5.205-16.572 19.881 0 14.673 8.928 19.881 16.572 19.881a19.15 19.15 0 0 0 3.818-.405c.003.131-.005.261.003.395.698 8.806 4.728 16.787 11.062 21.918l10.202 8.88.812.71a7.475 7.475 0 0 0 4.926 1.846 7.483 7.483 0 0 0 4.92-1.838l.82-.712 10.215-8.887c6.335-5.136 10.366-13.115 11.068-21.913.01-.133 0-.263.002-.395a19.25 19.25 0 0 0 3.826.402c7.646 0 16.572-5.207 16.572-19.881 0-14.676-8.926-19.881-16.572-19.881"/><path fill="#4d4c4e" d="M38.494 57.751c-.146.927-.253 1.875-.253 2.856 0 .398.036.788.063 1.183h23.91c.022-.395.056-.785.056-1.183 0-.978-.08-1.931-.217-2.856H38.495zm5.441 15.81l.133.112.581.505h11.213l.71-.617c1.057-.84 1.972-1.87 2.756-3.02H41.18c.786 1.15 1.696 2.182 2.753 3.02"/></svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 5.2 KiB |
1
static/images/integrations/logos/bitbucket.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="256" height="231" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><defs><linearGradient x1="108.633%" y1="13.818%" x2="46.927%" y2="78.776%" id="a"><stop stop-color="#0052CC" offset="18%"/><stop stop-color="#2684FF" offset="100%"/></linearGradient></defs><g fill="none"><path d="M101.272 152.561h53.449l12.901-75.32H87.06z"/><path d="M8.308 0A8.202 8.202 0 0 0 .106 9.516l34.819 211.373a11.155 11.155 0 0 0 10.909 9.31h167.04a8.202 8.202 0 0 0 8.201-6.89l34.82-213.752a8.202 8.202 0 0 0-8.203-9.514L8.308 0zm146.616 152.768h-53.315l-14.436-75.42h80.67l-12.919 75.42z" fill="#2684FF"/><path d="M244.61 77.242h-76.916l-12.909 75.36h-53.272l-62.902 74.663a11.105 11.105 0 0 0 7.171 2.704H212.73a8.196 8.196 0 0 0 8.196-6.884l23.686-145.843z" fill="url(#a)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 795 B |
|
Before Width: | Height: | Size: 16 KiB |
1
static/images/integrations/logos/clubhouse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" viewBox="0 0 288 224.3"><style id="style3">.st0{fill:#6515dd}</style><g id="g5" transform="translate(-144 -175.8)"><g id="g7"><g id="g9"><path class="st0" d="M164.9 358.3c-11.5 0-20.9 9.4-20.9 20.9 0 11.5 9.4 20.9 20.9 20.9 11.5 0 20.9-9.4 20.9-20.9 0-11.5-9.3-20.9-20.9-20.9z" id="path11" fill="#6515dd"/></g><path class="st0" d="M422.2 175.8l-131.6 42v-41.5l-141.9 45.3v120.3l122.4-39.1v41.3L432 292.8l-43.6-42.6 33.8-74.4zM271.1 282.2L168.3 315v-79.1l102.8-32.8v79.1zm124.5 1.7l-105 33.5v-79l96.7-30.9-22.2 46.8 30.5 29.6z" id="path13" fill="#6515dd"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 622 B |
|
Before Width: | Height: | Size: 7.0 KiB |
1
static/images/integrations/logos/dialogflow.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="1.205 -0.893 146.076 187.57" width="142.08" height="183.57"><defs><path d="M144.28 40.13L73.26 81.15 2.2 40.13v82.03l35.53 20.49v41.03l106.55-61.52V40.13z" id="a"/><path d="M73.26 82.14L2.2 41.12 73.26.11l71.02 41.01-71.02 41.02z" id="b"/><path d="M72 80.89L2.65 40.85l-.45.27 71.06 41.02 71.02-41.02-1.67-.99L72 80.89z" id="c"/><path d="M73.26 82.65v-.51L2.65 41.36l-.45.27 71.06 41.02z" id="d"/></defs><use xlink:href="#a" fill="#ef6c00"/><use xlink:href="#a" fill-opacity="0" stroke="#000" stroke-opacity="0"/><use xlink:href="#b" fill="#ff9800"/><use xlink:href="#b" fill-opacity="0" stroke="#000" stroke-opacity="0"/><use xlink:href="#c" fill="#ff9800"/><use xlink:href="#c" fill-opacity="0" stroke="#000" stroke-opacity="0"/><use xlink:href="#d" fill="#ff9800"/><use xlink:href="#d" fill-opacity="0" stroke="#000" stroke-opacity="0"/></svg>
|
||||
|
After Width: | Height: | Size: 938 B |
|
Before Width: | Height: | Size: 4.4 KiB |
1
static/images/integrations/logos/discourse.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -1 104 106"><g data-name="Layer 2"><g data-name="Layer 3"><path d="M51.87 0C23.71 0 0 22.83 0 51v52.81l51.86-.05c28.16 0 51-23.71 51-51.87S80 0 51.87 0z" fill="#231f20"/><path d="M52.37 19.74a31.62 31.62 0 0 0-27.79 46.67l-5.72 18.4 20.54-4.64a31.61 31.61 0 1 0 13-60.43z" fill="#fff9ae"/><path d="M77.45 32.12a31.6 31.6 0 0 1-38.05 48l-20.54 4.7 20.91-2.47a31.6 31.6 0 0 0 37.68-50.23z" fill="#00aeef"/><path d="M71.63 26.29A31.6 31.6 0 0 1 38.8 78l-19.94 6.82 20.54-4.65a31.6 31.6 0 0 0 32.23-53.88z" fill="#00a94f"/><path d="M26.47 67.11a31.61 31.61 0 0 1 51-35 31.61 31.61 0 0 0-52.89 34.3l-5.72 18.4z" fill="#f15d22"/><path d="M24.58 66.41a31.61 31.61 0 0 1 47.05-40.12 31.61 31.61 0 0 0-49 39.63l-3.76 18.9z" fill="#e31b23"/></g></g></svg>
|
||||
|
After Width: | Height: | Size: 796 B |
|
Before Width: | Height: | Size: 3.6 KiB |
1
static/images/integrations/logos/flock.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-0.921 210.038 228.723 221.823" width="224.72" height="217.82"><defs><path d="M205.23 383.31c-.42-6.57 1.43-13.93 3.29-19.29 1.15-2.5 2.15-5.07 3.07-7.65v-.07c20.08-56.67-9.57-118.91-66.31-138.99-56.74-20.08-118.84 9.65-138.92 66.32-20.08 56.66 9.58 118.91 66.32 138.99 31.29 11.07 65.95 7.29 94.11-10.36 2.86-1.36 5.29-2.15 6.64-1.58 14.44 6.08 30.23 7.94 45.67 5.22 2.71-.43 9.64-3 2.71-8.15-7-5.14-15.72-12.14-16.58-24.44z" id="a"/><path d="M150.07 270.55c6.79 0 12.29 5.5 12.29 12.29v.5c0 6.79-5.5 12.29-12.29 12.29H76.89c-6.79 0-12.29-5.5-12.29-12.29v-.5c0-6.79 5.5-12.29 12.29-12.29h73.18z" id="b"/><path d="M123.13 307.78c6.79 0 12.29 5.5 12.29 12.29v.57c0 6.79-5.5 12.29-12.29 12.29H76.89c-6.79 0-12.29-5.5-12.29-12.29v-.57c0-6.79 5.5-12.29 12.29-12.29h46.24z" id="c"/><path d="M85.25 344.37c6.79 0 12.29 5.5 12.29 12.29v.5c0 6.79-5.5 12.29-12.29 12.29h-8.36c-6.79 0-12.29-5.5-12.29-12.29v-.5c0-6.79 5.5-12.29 12.29-12.29h8.36z" id="d"/></defs><use xlink:href="#a" fill="#0abe51"/><use xlink:href="#a" fill-opacity="0" stroke="#000" stroke-opacity="0"/><use xlink:href="#b" fill="#fff"/><use xlink:href="#b" fill-opacity="0" stroke="#000" stroke-opacity="0"/><use xlink:href="#c" fill="#fff"/><use xlink:href="#c" fill-opacity="0" stroke="#000" stroke-opacity="0"/><use xlink:href="#d" fill="#fff"/><use xlink:href="#d" fill-opacity="0" stroke="#000" stroke-opacity="0"/></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 193 KiB After Width: | Height: | Size: 480 B |
|
Before Width: | Height: | Size: 3.1 KiB |
1
static/images/integrations/logos/gocd.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 737 411"><path d="M491.7 312.8c-4.2 11.3-10.2 21-18 29.1-7.8 8.1-17.1 14.4-28 18.8s-22.9 6.7-36 6.7c-20.4 0-37.9-5.1-52.4-15.2s-24-23.9-28.5-41.5h29.6c2.9 6.4 6.5 11.6 11 15.5 4.4 3.9 9.2 6.8 14.2 8.8s9.8 3.3 14.5 4 8.5 1 11.7 1c10.9 0 20.1-1.9 27.8-5.8 7.7-3.9 13.9-8.9 18.6-15 4.8-6.1 8.2-13 10.3-20.8 2.1-7.8 3.2-15.5 3.2-23.3v-18c-6.2 8.4-14.4 15.6-24.5 21.5s-21.4 8.8-33.8 8.8-23.9-2.3-34.3-7-19.5-11.1-27.1-19.3c-7.7-8.2-13.7-17.8-18-28.6-4.3-10.9-6.5-22.5-6.5-35s2.2-24.1 6.5-35.1 10.3-20.5 18-28.6c7.7-8.1 16.7-14.5 27.1-19.3s21.9-7.2 34.3-7.2c12.7 0 24.2 3.1 34.6 9.3 10.4 6.2 18.6 13.7 24.6 22.3v-27.3h27.3v163.5c.2 13.8-1.9 26.4-6.2 37.7zm-26.6-139.9c-3.1-7.8-7.3-14.6-12.7-20.5-5.3-5.9-11.5-10.5-18.5-13.8-7-3.3-14.5-5-22.5-5s-15.5 1.7-22.6 5c-7.1 3.3-13.2 7.9-18.3 13.8-5.1 5.9-9.2 12.7-12.2 20.5-3 7.8-4.5 16.1-4.5 25 0 8.7 1.5 16.9 4.5 24.6 3 7.8 7 14.5 12.2 20.3 5.1 5.8 11.2 10.3 18.3 13.7 7.1 3.3 14.7 5 22.6 5 8 0 15.5-1.7 22.5-5s13.2-7.9 18.5-13.7c5.3-5.8 9.5-12.5 12.7-20.3 3.1-7.8 4.7-16 4.7-24.6 0-8.9-1.6-17.2-4.7-25zm173.3-58.4c10.5 4.8 19.6 11.3 27.3 19.5 7.7 8.2 13.7 17.8 18.1 28.8 4.4 11 6.7 22.7 6.7 35.1s-2.2 24-6.7 34.8c-4.4 10.8-10.5 20.2-18.1 28.3-7.7 8.1-16.8 14.5-27.3 19.1s-21.9 7-34.1 7c-12.2 0-23.5-2.3-34-7s-19.5-11-27.3-19.1c-7.8-8.1-13.9-17.5-18.3-28.3s-6.7-22.4-6.7-34.8 2.2-24.1 6.7-35.1c4.4-11 10.5-20.6 18.3-28.8 7.8-8.2 16.9-14.7 27.3-19.5s21.8-7.2 34-7.2 23.6 2.4 34.1 7.2zm-11.6 141.7c7-3.3 13.2-7.8 18.5-13.5 5.3-5.7 9.5-12.4 12.5-20.1 3-7.8 4.5-16 4.5-24.6 0-8.9-1.5-17.3-4.5-25.1-3-7.9-7.2-14.7-12.5-20.5-5.3-5.8-11.5-10.4-18.5-13.8s-14.5-5.2-22.5-5.2-15.5 1.7-22.5 5.2-13.1 8-18.3 13.8-9.3 12.6-12.3 20.5-4.5 16.3-4.5 25.1c0 8.7 1.5 16.9 4.5 24.6 3 7.8 7.1 14.5 12.3 20.1 5.2 5.7 11.3 10.2 18.3 13.5 7 3.3 14.5 5 22.5 5s15.5-1.7 22.5-5zM70.9 326c-4.6 0-9.2-1.1-13.4-3.4-9.2-4.9-15-14.5-15-25V184.3c0-15.7 12.7-28.3 28.3-28.3s28.3 12.7 28.3 28.3v60.4l90.6-60.4L55.1 94.5c-13-8.7-16.5-26.3-7.9-39.3 8.7-13 26.3-16.5 39.3-7.9l170.1 113.4c7.9 5.3 12.6 14.1 12.6 23.6s-4.7 18.3-12.6 23.6l-170 113.3c-4.8 3.2-10.2 4.8-15.7 4.8z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 742 B |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 1018 B |
|
Before Width: | Height: | Size: 22 KiB |
1
static/images/integrations/logos/groove.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="225.038" height="298.103"><defs><clipPath id="a"><path d="M0 1080h1920V0H0v1080z"/></clipPath></defs><g clip-path="url(#a)" transform="matrix(1.25 0 0 -1.25 -1083.117 819.262)"><path d="M946.697 450.868c-19.84 0-38.464 5.1-54.63 14.008l-16.964-29.537c21.176-11.707 45.584-18.412 71.594-18.412 26.01 0 50.418 6.705 71.594 18.412l-16.962 29.537c-16.167-8.909-34.79-14.008-54.632-14.008" fill="#0ba0be"/><path d="M946.433 528.849c-25.605 0-45.278 20.922-45.278 46.527 0 25.606 19.673 46.528 45.278 46.528 25.918 0 44.966-20.922 44.966-46.528 0-25.605-19.048-46.527-44.966-46.527m100.09 90.56v36c-15 0-21.906-.92-25.98-2.784-4.071-1.864-3.494-1.775-7.278-4.571-3.456-2.555-9.3-8.65-13.073-12.84-14.08 12.589-32.834 20.1-53.76 20.1-45.277 0-79.938-34.66-79.938-79.938 0-44.965 34.66-80.251 79.939-80.251 44.966 0 79.939 35.286 79.939 80.25 0 16.47-4.644 31.52-12.695 44.023.022.002.062.012.076.012h32.77z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 959 B |
1
static/images/integrations/logos/instagra_m.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="132.004" height="132" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="b"><stop offset="0" stop-color="#3771c8"/><stop stop-color="#3771c8" offset=".128"/><stop offset="1" stop-color="#60f" stop-opacity="0"/></linearGradient><linearGradient id="a"><stop offset="0" stop-color="#fd5"/><stop offset=".1" stop-color="#fd5"/><stop offset=".5" stop-color="#ff543e"/><stop offset="1" stop-color="#c837ab"/></linearGradient><radialGradient id="c" cx="158.429" cy="578.088" r="65" xlink:href="#a" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0 -1.98198 1.8439 0 -1031.402 454.004)" fx="158.429" fy="578.088"/><radialGradient id="d" cx="147.694" cy="473.455" r="65" xlink:href="#b" gradientUnits="userSpaceOnUse" gradientTransform="matrix(.17394 .86872 -3.5818 .71718 1648.348 -458.493)" fx="147.694" fy="473.455"/></defs><path fill="url(#c)" d="M65.03 0C37.888 0 29.95.028 28.407.156c-5.57.463-9.036 1.34-12.812 3.22-2.91 1.445-5.205 3.12-7.47 5.468C4 13.126 1.5 18.394.595 24.656c-.44 3.04-.568 3.66-.594 19.188-.01 5.176 0 11.988 0 21.125 0 27.12.03 35.05.16 36.59.45 5.42 1.3 8.83 3.1 12.56 3.44 7.14 10.01 12.5 17.75 14.5 2.68.69 5.64 1.07 9.44 1.25 1.61.07 18.02.12 34.44.12 16.42 0 32.84-.02 34.41-.1 4.4-.207 6.955-.55 9.78-1.28a27.22 27.22 0 0 0 17.75-14.53c1.765-3.64 2.66-7.18 3.065-12.317.088-1.12.125-18.977.125-36.81 0-17.836-.04-35.66-.128-36.78-.41-5.22-1.305-8.73-3.127-12.44-1.495-3.037-3.155-5.305-5.565-7.624C116.9 4 111.64 1.5 105.372.596 102.335.157 101.73.027 86.19 0H65.03z" transform="translate(1.004 1)"/><path fill="url(#d)" d="M65.03 0C37.888 0 29.95.028 28.407.156c-5.57.463-9.036 1.34-12.812 3.22-2.91 1.445-5.205 3.12-7.47 5.468C4 13.126 1.5 18.394.595 24.656c-.44 3.04-.568 3.66-.594 19.188-.01 5.176 0 11.988 0 21.125 0 27.12.03 35.05.16 36.59.45 5.42 1.3 8.83 3.1 12.56 3.44 7.14 10.01 12.5 17.75 14.5 2.68.69 5.64 1.07 9.44 1.25 1.61.07 18.02.12 34.44.12 16.42 0 32.84-.02 34.41-.1 4.4-.207 6.955-.55 9.78-1.28a27.22 27.22 0 0 0 17.75-14.53c1.765-3.64 2.66-7.18 3.065-12.317.088-1.12.125-18.977.125-36.81 0-17.836-.04-35.66-.128-36.78-.41-5.22-1.305-8.73-3.127-12.44-1.495-3.037-3.155-5.305-5.565-7.624C116.9 4 111.64 1.5 105.372.596 102.335.157 101.73.027 86.19 0H65.03z" transform="translate(1.004 1)"/><path fill="#fff" d="M66.004 18c-13.036 0-14.672.057-19.792.29-5.11.234-8.598 1.043-11.65 2.23-3.157 1.226-5.835 2.866-8.503 5.535-2.67 2.668-4.31 5.346-5.54 8.502-1.19 3.053-2 6.542-2.23 11.65C18.06 51.327 18 52.964 18 66s.058 14.667.29 19.787c.235 5.11 1.044 8.598 2.23 11.65 1.227 3.157 2.867 5.835 5.536 8.503 2.667 2.67 5.345 4.314 8.5 5.54 3.054 1.187 6.543 1.996 11.652 2.23 5.12.233 6.755.29 19.79.29 13.037 0 14.668-.057 19.788-.29 5.11-.234 8.602-1.043 11.656-2.23 3.156-1.226 5.83-2.87 8.497-5.54 2.67-2.668 4.31-5.346 5.54-8.502 1.18-3.053 1.99-6.542 2.23-11.65.23-5.12.29-6.752.29-19.788 0-13.036-.06-14.672-.29-19.792-.24-5.11-1.05-8.598-2.23-11.65-1.23-3.157-2.87-5.835-5.54-8.503-2.67-2.67-5.34-4.31-8.5-5.535-3.06-1.187-6.55-1.996-11.66-2.23-5.12-.233-6.75-.29-19.79-.29zm-4.306 8.65c1.278-.002 2.704 0 4.306 0 12.816 0 14.335.046 19.396.276 4.68.214 7.22.996 8.912 1.653 2.24.87 3.837 1.91 5.516 3.59 1.68 1.68 2.72 3.28 3.592 5.52.657 1.69 1.44 4.23 1.653 8.91.23 5.06.28 6.58.28 19.39s-.05 14.33-.28 19.39c-.214 4.68-.996 7.22-1.653 8.91-.87 2.24-1.912 3.835-3.592 5.514-1.68 1.68-3.275 2.72-5.516 3.59-1.69.66-4.232 1.44-8.912 1.654-5.06.23-6.58.28-19.396.28-12.817 0-14.336-.05-19.396-.28-4.68-.216-7.22-.998-8.913-1.655-2.24-.87-3.84-1.91-5.52-3.59-1.68-1.68-2.72-3.276-3.592-5.517-.657-1.69-1.44-4.23-1.653-8.91-.23-5.06-.276-6.58-.276-19.398s.046-14.33.276-19.39c.214-4.68.996-7.22 1.653-8.912.87-2.24 1.912-3.84 3.592-5.52 1.68-1.68 3.28-2.72 5.52-3.592 1.692-.66 4.233-1.44 8.913-1.655 4.428-.2 6.144-.26 15.09-.27zm29.928 7.97a5.76 5.76 0 1 0 5.76 5.758c0-3.18-2.58-5.76-5.76-5.76zm-25.622 6.73c-13.613 0-24.65 11.037-24.65 24.65 0 13.613 11.037 24.645 24.65 24.645C79.617 90.645 90.65 79.613 90.65 66S79.616 41.35 66.003 41.35zm0 8.65c8.836 0 16 7.163 16 16 0 8.836-7.164 16-16 16-8.837 0-16-7.164-16-16 0-8.837 7.163-16 16-16z"/></svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 5.5 KiB |
1
static/images/integrations/logos/jira.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 73.275 75.76" id="svg2"><defs id="defs4"><style id="style6"/><linearGradient id="linear-gradient" x1="34.64" y1="15.35" x2="19" y2="30.99" gradientUnits="userSpaceOnUse"><stop offset=".18" stop-color="#0052cc" id="stop9"/><stop offset="1" stop-color="#2684ff" id="stop11"/></linearGradient><linearGradient id="linear-gradient-2" x1="38.78" y1="60.28" x2="54.39" y2="44.67" xlink:href="#linear-gradient"/><linearGradient xlink:href="#linear-gradient" id="linearGradient3027" gradientUnits="userSpaceOnUse" x1="34.64" y1="15.35" x2="19" y2="30.99"/><linearGradient xlink:href="#linear-gradient" id="linearGradient3045" gradientUnits="userSpaceOnUse" x1="34.64" y1="15.35" x2="19" y2="30.99"/><linearGradient xlink:href="#linear-gradient" id="linearGradient3047" x1="38.78" y1="60.28" x2="54.39" y2="44.67"/><linearGradient xlink:href="#linear-gradient" id="linearGradient3050" x1="38.78" y1="60.28" x2="54.39" y2="44.67" gradientTransform="translate(-.003)"/><linearGradient xlink:href="#linear-gradient" id="linearGradient3053" gradientUnits="userSpaceOnUse" x1="34.64" y1="15.35" x2="19" y2="30.99" gradientTransform="translate(-.003)"/></defs><path d="M72.397 35.76l-32.6-32.6L36.637 0l-24.54 24.54L.877 35.76a3 3 0 0 0 0 4.24l22.42 22.42 13.34 13.34 24.54-24.54.38-.38L72.397 40a3 3 0 0 0 0-4.24zm-35.76 13.32l-11.2-11.2 11.2-11.2 11.2 11.2z" id="path42" fill="#2684ff"/><path d="M36.637 26.68a18.86 18.86 0 0 1-.08-26.59l-24.51 24.5 13.34 13.34 11.25-11.25z" id="path44" fill="url(#linearGradient3053)"/><path d="M47.867 37.85l-11.23 11.23a18.86 18.86 0 0 1 0 26.68l24.57-24.57z" id="path46" fill="url(#linearGradient3050)"/></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 6.2 KiB |
1
static/images/integrations/logos/opsgenie.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-0.99 262.096 91.39 108.05" width="87.39" height="104.05"><defs><path d="M43.7 263.1c-14.34 0-25.96 11.62-25.96 25.96 0 14.34 11.62 25.96 25.96 25.96 14.34 0 25.97-11.62 25.97-25.96 0-14.34-11.63-25.96-25.97-25.96z" id="a"/><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="43.7" y1="271.73" x2="43.7" y2="325.04"><stop offset="0%" stop-color="#2684ff"/><stop offset="82%" stop-color="#0052cc"/></linearGradient><path d="M.38 323.54a2.908 2.908 0 0 1 1.13-3.96c.04-.03.09-.05.13-.07 1.97-.97 17.7-8.69 19.67-9.65 1.37-.67 3.03-.17 3.79 1.16a97.199 97.199 0 0 0 42.21 38.2 125.638 125.638 0 0 1-21.39 17.29c-1.36.85-3.07.85-4.43 0A125.16 125.16 0 0 1 .38 323.54z" id="c"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="27.72" y1="323.54" x2="45.58" y2="360.91"><stop offset="0%" stop-color="#2684ff"/><stop offset="62%" stop-color="#0052cc"/></linearGradient><path d="M87.03 323.54c.78-1.41.28-3.18-1.12-3.96-.04-.03-.09-.05-.13-.07-1.97-.97-17.71-8.69-19.68-9.65a2.912 2.912 0 0 0-3.8 1.16 97.12 97.12 0 0 1-42.2 38.2 125.25 125.25 0 0 0 21.39 17.29c1.36.85 3.07.85 4.43 0a125.16 125.16 0 0 0 41.11-42.97z" id="e"/></defs><use xlink:href="#a" fill="url(#b)"/><use xlink:href="#a" fill-opacity="0" stroke="#000" stroke-opacity="0"/><use xlink:href="#c" fill="url(#d)"/><use xlink:href="#c" fill-opacity="0" stroke="#000" stroke-opacity="0"/><use xlink:href="#e" fill="#2684ff"/><use xlink:href="#e" fill-opacity="0" stroke="#000" stroke-opacity="0"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 42 KiB |
1
static/images/integrations/logos/raygun.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80"><path fill="#303847" d="M0 0h80v80H0z"/><path fill="#FFF" d="M41.7 38.6l-3.5-.6 1.6-7.4-6.2 9.3 3.6.6-1.7 7.8z"/><path d="M52.2 59.8c-.3-3.4-.5-6.8-.6-10.2-.9.1-1.7.2-2.6.2-2.9 3-6.9 4.8-11.1 4.8-5.7 0-10.9-3.2-13.5-8.2-.3-.1-.7-.2-1-.4l.5 1.1-2-.3c-.6-.1-1.2-.1-1.8-.2 1.5 3 4 5.7 7.1 7.8 1.9 2.1 3.1 4.9 3.1 8 0 1.9-.5 3.8-1.3 5.4-.2.3-.1 1 .4 1.2 1.5.6 3.1 1 4.7 1 .8 0 1.5-.1 2.2-.2-.2-.8-.3-1.6-.3-2.4 0-3.1 1.2-5.9 3.1-8 1.6.3 4.3.6 3.9.6 0 1.7.4 3.3 1.1 4.7l1-1c-.3-1-.5-2-.5-3v-.5h-.1 1.9c2.1 0 4-.2 5.8-.4zM37.9 24.2c4.2 0 8.2 1.7 11.1 4.8.9 0 1.7.1 2.6.2.1-3.4.3-6.7.6-10.1V19c-1.8-.3-3.6-.4-5.5-.4-13.5 0-24.7 6.8-27.7 15.9 1.8-.8 3.6-1.5 5.4-2.2 2.6-4.9 7.8-8.1 13.5-8.1z" fill="#FFF"/><circle fill="#FFF" cx="71" cy="39.6" r="4"/><path fill="#FFF" d="M32.4 18.4c1.4 0 2.9.1 4.3.3 1.2-.3 2.4-.6 3.6-.8-4.1-1.5-8.6-2.3-13.2-2.3-4 0-7.8.6-11.4 1.7l1.8 4.7c4.4-2.3 9.5-3.6 14.9-3.6zm20.2 21c0 6.8.3 13.5.8 20.2 1.2-.2 2.4-.5 3.5-.8.5-6.4.7-12.9.7-19.4 0-6.5-.2-13-.7-19.4-1.1-.3-2.3-.6-3.5-.8-.6 6.7-.8 13.4-.8 20.2z"/><path fill="#FFF" d="M33.7 19.6h-1.3c-6.2 0-12.2 1.8-17.3 5.1l4.8 5.3c2.8-4.5 7.8-8.2 13.8-10.4zm32.5 21.6c-.2-.5-.3-1.1-.3-1.7 0-.6.1-1.2.3-1.7-2.8 0-5.3-.9-7.5-2.3v8c2.1-1.4 4.7-2.3 7.5-2.3zm-14.8-1.8c0-3 .1-6 .2-9.1-1-.1-2.1-.2-3.1-.2-2.6-2.9-6.3-4.8-10.5-4.8-5.6 0-10.4 3.3-12.7 8-4.5 1.5-8.8 3.6-12.8 6.1 1.7 1.1 3.5 2.1 5.3 3-4.6 1.1-8.9 2.9-12.7 5.4 3.8-1.5 8-2.4 12.3-2.4 1.6 0 3.1.1 4.7.3-.5-1.2-.8-2.5-1-3.8.3.8.6 1.6 1 2.4 1.1.4 2.1.8 3.2 1.2 2.3 4.7 7.1 8 12.7 8 4.2 0 8-1.8 10.5-4.8 1-.1 2.1-.1 3.1-.2-.2-3.1-.2-6.1-.2-9.1zM37.9 51.3C31.3 51.3 26 46 26 39.4c0-6.6 5.3-11.9 11.9-11.9s11.9 5.3 11.9 11.9c0 6.6-5.3 11.9-11.9 11.9z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
1
static/images/integrations/logos/statuspage.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1.001 277.155 94.595 70.721" width="90.6" height="66.72"><defs><path d="M45.3 302.46c-11.72 0-21.21 9.49-21.21 21.21 0 11.71 9.49 21.21 21.21 21.21 11.71 0 21.21-9.5 21.21-21.21 0-11.72-9.5-21.21-21.21-21.21z" id="a"/><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="45.3" y1="337.58" x2="45.3" y2="300"><stop offset="0%" stop-color="#2684ff"/><stop offset="82%" stop-color="#0052cc"/></linearGradient><path d="M11.96 312.62c.87 1.02 2.4 1.14 3.42.28l.03-.03c18.44-16.53 41.27-16.53 59.76 0 1.01.89 2.55.78 3.43-.23.01 0 .01-.01.02-.02l11.4-13.49c.86-1.02.74-2.54-.28-3.41-26.77-23.42-62.13-23.42-88.89 0a2.423 2.423 0 0 0-.28 3.41l11.39 13.49z" id="c"/></defs><use xlink:href="#a" fill="url(#b)"/><use xlink:href="#a" fill-opacity="0" stroke="#000" stroke-opacity="0"/><use xlink:href="#c" fill="#2684ff"/><use xlink:href="#c" fill-opacity="0" stroke="#000" stroke-opacity="0"/></svg>
|
||||
|
After Width: | Height: | Size: 987 B |
|
Before Width: | Height: | Size: 4.1 KiB |
1
static/images/integrations/logos/trello.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 102 101.99"><defs><linearGradient id="a" x1="51" y1="101.99" x2="51" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#0b7abf"/><stop offset="1" stop-color="#368dcc"/></linearGradient></defs><g data-name="Layer 2"><path d="M89.25 0h-76.5A12.75 12.75 0 0 0 0 12.75v76.5A12.75 12.75 0 0 0 12.75 102h76.5A12.75 12.75 0 0 0 102 89.25v-76.5A12.75 12.75 0 0 0 89.25 0zM44.37 77.26a6.12 6.12 0 0 1-6.12 6.12H19.38a6.12 6.12 0 0 1-6.12-6.12V19.38a6.12 6.12 0 0 1 6.12-6.12h18.87a6.12 6.12 0 0 1 6.12 6.12zm44.37-25.5a6.12 6.12 0 0 1-6.12 6.12H63.75a6.12 6.12 0 0 1-6.12-6.12V19.38a6.12 6.12 0 0 1 6.12-6.12h18.87a6.12 6.12 0 0 1 6.12 6.12z" fill="url(#a)" data-name="Layer 1"/></g></svg>
|
||||
|
After Width: | Height: | Size: 743 B |
|
Before Width: | Height: | Size: 968 B After Width: | Height: | Size: 968 B |
BIN
static/images/integrations/logos/xkcd.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -177,24 +177,6 @@ exports.short_huddle_name = function (huddle) {
|
||||
return names.join(', ');
|
||||
};
|
||||
|
||||
exports.huddle_fraction_present = function (huddle) {
|
||||
var user_ids = huddle.split(',');
|
||||
|
||||
var num_present = 0;
|
||||
_.each(user_ids, function (user_id) {
|
||||
if (presence.is_active(user_id)) {
|
||||
num_present += 1;
|
||||
}
|
||||
});
|
||||
|
||||
if (num_present === user_ids.length) {
|
||||
return 1;
|
||||
} else if (num_present !== 0) {
|
||||
return 0.5;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
function focus_lost() {
|
||||
// When we become idle, we don't immediately send anything to the
|
||||
// server; instead, we wait for our next periodic update, since
|
||||
@@ -280,7 +262,7 @@ exports.update_huddles = function () {
|
||||
user_ids_string: huddle,
|
||||
name: exports.full_huddle_name(huddle),
|
||||
href: hash_util.huddle_with_uri(huddle),
|
||||
fraction_present: exports.huddle_fraction_present(huddle),
|
||||
fraction_present: buddy_data.huddle_fraction_present(huddle),
|
||||
short_name: exports.short_huddle_name(huddle),
|
||||
};
|
||||
});
|
||||
@@ -393,22 +375,26 @@ exports.update_presence_info = function (email, info, server_time) {
|
||||
presence.set_info_for_user(user_id, info, server_time);
|
||||
exports.redraw_user(user_id);
|
||||
exports.update_huddles();
|
||||
pm_list.update_private_messages();
|
||||
};
|
||||
|
||||
exports.on_set_away = function (user_id) {
|
||||
user_status.set_away(user_id);
|
||||
exports.redraw_user(user_id);
|
||||
pm_list.update_private_messages();
|
||||
};
|
||||
|
||||
exports.on_revoke_away = function (user_id) {
|
||||
user_status.revoke_away(user_id);
|
||||
exports.redraw_user(user_id);
|
||||
pm_list.update_private_messages();
|
||||
};
|
||||
|
||||
exports.redraw = function () {
|
||||
exports.build_user_sidebar();
|
||||
exports.user_cursor.redraw();
|
||||
exports.update_huddles();
|
||||
pm_list.update_private_messages();
|
||||
};
|
||||
|
||||
exports.reset_users = function () {
|
||||
|
||||