Compare commits

...

24 Commits

Author SHA1 Message Date
a461444bed make version (instead of make release) 2023-10-08 13:53:45 +00:00
1307f87912 Simplify chapril release process 2023-10-07 08:15:40 +00:00
23cf858a02 Add some bash safeguards in README.charpil.md 2023-10-07 08:13:09 +00:00
b49146b36f [Branding] Customize homepage's text and links + CSS adjustments. 2023-10-07 08:13:09 +00:00
8d67dce865 [Branding] Replace Converse's logo with Chapril's logo. 2023-10-07 08:13:07 +00:00
543807aa50 Create a README for Chapril's build. 2023-10-07 08:12:53 +00:00
JC Brand
82a8c3f9fc Release 10.1.6 2023-08-31 21:30:48 +02:00
JC Brand
3e680e88d8 Fix import path 2023-08-31 21:20:40 +02:00
JC Brand
005f5374f0 Fixes #3246 2023-08-31 21:20:40 +02:00
JC Brand
79bb8e76ce Fix GIF rendering artifacts related to patching 2023-08-31 21:20:40 +02:00
JC Brand
61192f91d9 Fix GIF rendering issue
Remove the GIF parsing code from this repo and instead add a dependency on gifuct-js.
2023-08-31 21:20:40 +02:00
JC Brand
e31d4c7bac Release 10.1.5
Refine the `dist` step by creating a proper temporary file.

I spent a lot of time trying to pinpoint the underlying cause, why
translation chunk files are empty when generating a bundle with newer JS
features (i.e. not pinning preset-env to IE11) but couldn't find it.
2023-06-30 06:38:40 +02:00
JC Brand
c30569dfd3 Release 10.1.5
Found another bug while trying to make the release.

Running `npm run nodeps` last breaks dynamic importing of the DayJS
translations. I'm not sure why, I think maybe because of broken `.map`
files.

The fix for now is to move the js-po files out of the way, and then copy
them back in after running `npm run build`.

Hopefully all of this won't be necessary with gettext 0.22 which should
support template literals
2023-06-29 23:41:15 +02:00
JC Brand
5e02b9bd5d Release 10.1.5 (this time hopefully for real)
As I was making the release, I found a bug in the Makefile that still
prevented the locale JSON files from being properly generated.
2023-06-29 23:09:49 +02:00
JC Brand
9114db8764 Release 10.1.5 2023-06-29 22:29:11 +02:00
JC Brand
bc7621c25d Updates #3207 - Generate po files in the release checkout
Refactor the Makefile somewhat.

- Rename `make release` to `make version`
- Add `make release-checkout` which checks out the release branch
2023-06-29 22:16:19 +02:00
ssantos
ae518aa2c3 Translated using Weblate (Portuguese)
Currently translated at 99.8% (539 of 540 strings)

Translation: Converse.js/Translations
Translate-URL: https://hosted.weblate.org/projects/conversejs/translations/pt/
2023-06-29 21:55:15 +02:00
josé m
e4a4b2819c Translated using Weblate (Galician)
Currently translated at 100.0% (540 of 540 strings)

Translation: Converse.js/Translations
Translate-URL: https://hosted.weblate.org/projects/conversejs/translations/gl/
2023-06-29 21:55:15 +02:00
JC Brand
5310021b67 Modernize the i18n code.
- Remove old deprecated API methods `systemLanguage`, `browserLanguage`
  and `userLanguage`.
- Add types via JSDoc
2023-06-29 09:43:53 +02:00
SilverYoCha
e18fdd56b1 Fix #3209.
Fixing some technical errors when avoiding importing the `converse` global with bootstrap modal API.
2023-06-27 11:07:35 +02:00
JC Brand
94963662e7 Fix ordering or args 2023-06-25 11:22:16 +02:00
JC Brand
4f14d50f5d Check out depth of 1 when deploying 2023-06-25 11:15:46 +02:00
JC Brand
699ab71f21 Larger sponsor image 2023-06-25 11:13:24 +02:00
JC Brand
daeb641530 Postrelease 2023-06-25 11:09:50 +02:00
35 changed files with 488 additions and 920 deletions

View File

@ -1,6 +1,17 @@
# Changelog # Changelog
## 10.1.3 (2023-06-25) ## 10.1.6 (2023-08-31)
- #3246: Badge color not responsive to dark theme
- Fix a GIF rendering bug that causes a memory overflow
## 10.1.5 (2023-06-29)
- #3209: Fix error when importing the `converse` global with bootstrap modal API
- #3207: `.po` translation files weren't included in previous release
- Updated Galician and Portuguese translations
## 10.1.4 (2023-06-25)
- Fix `dist` directory not included in NPM package - Fix `dist` directory not included in NPM package

View File

@ -2,7 +2,7 @@
* *
* An XMPP chat client that runs in the browser. * An XMPP chat client that runs in the browser.
* *
* Version: 10.1.4 * Version: 10.1.6
* *
* Copyright: JC Brand 2013-2018 * Copyright: JC Brand 2013-2018
* Except for 3rd party dependencies. * Except for 3rd party dependencies.

View File

@ -65,10 +65,7 @@ certs:
######################################################################## ########################################################################
## Translation machinery ## Translation machinery
dist/converse-no-dependencies.js: src webpack/webpack.common.js webpack/webpack.nodeps.js @converse/headless node_modules GETTEXT = $(XGETTEXT) --from-code=UTF-8 --language=JavaScript --keyword=__ --keyword=___ --keyword=i18n_ --force-po --output=src/i18n/converse.pot --package-name=Converse.js --copyright-holder="Jan-Carel Brand" --package-version=10.1.6 dist/converse-no-dependencies.js -c
npm run nodeps
GETTEXT = $(XGETTEXT) --from-code=UTF-8 --language=JavaScript --keyword=__ --keyword=___ --keyword=i18n_ --force-po --output=src/i18n/converse.pot --package-name=Converse.js --copyright-holder="Jan-Carel Brand" --package-version=10.1.4 dist/converse-no-dependencies.js -c
src/i18n/converse.pot: dist/converse-no-dependencies.js src/i18n/converse.pot: dist/converse-no-dependencies.js
$(GETTEXT) 2>&1 > /dev/null; exit $$?; $(GETTEXT) 2>&1 > /dev/null; exit $$?;
@ -85,10 +82,8 @@ po:
######################################################################## ########################################################################
## Release management ## Release management
.PHONY: release .PHONY: version
release: version:
rm -rf release && mkdir release
cd release
$(SED) -i '/^export const VERSION_NAME =/s/=.*/= "v$(VERSION)";/' src/headless/shared/constants.js $(SED) -i '/^export const VERSION_NAME =/s/=.*/= "v$(VERSION)";/' src/headless/shared/constants.js
$(SED) -i '/Version:/s/:.*/: $(VERSION)/' COPYRIGHT $(SED) -i '/Version:/s/:.*/: $(VERSION)/' COPYRIGHT
$(SED) -i '/Project-Id-Version:/s/:.*/: Converse.js $(VERSION)\n"/' src/i18n/converse.pot $(SED) -i '/Project-Id-Version:/s/:.*/: Converse.js $(VERSION)\n"/' src/i18n/converse.pot
@ -105,14 +100,18 @@ release:
make po make po
make dist make dist
release-checkout:
git clone git@github.com:conversejs/converse.js.git --depth 1 --branch $(BRANCH) release-$(BRANCH)
cd release-$(BRANCH) && make dist
.PHONY: publish .PHONY: publish
publish: publish:
git clone git@github.com:conversejs/converse.js.git --depth 1 --branch $(BRANCH) release/ make release-checkout
cd release && make dist && npm pack && npm publish cd release-$(BRANCH) && npm pack && npm publish
cd release/src/headless && npm pack && npm publish cd release-$(BRANCH)/src/headless && npm pack && npm publish
find ./release/ -name "converse.js-*.tgz" -exec mv {} . \; find ./release-$(BRANCH)/ -name "converse.js-*.tgz" -exec mv {} . \;
find ./release/src/headless -name "converse-headless-*.tgz" -exec mv {} . \; find ./release-$(BRANCH)/src/headless -name "converse-headless-*.tgz" -exec mv {} . \;
rm -rf release rm -rf release-$(BRANCH)
.PHONY: postrelease .PHONY: postrelease
postrelease: postrelease:
@ -120,7 +119,7 @@ postrelease:
.PHONY: deploy .PHONY: deploy
deploy: deploy:
git clone --branch v$(VERSION) git@github.com:conversejs/converse.js.git $(VERSION) git clone --branch v$(VERSION) git@github.com:conversejs/converse.js.git --depth 1 $(VERSION)
cd $(VERSION) && make node && ASSET_PATH=https://cdn.conversejs.org/$(VERSION)/dist/ make dist && make doc cd $(VERSION) && make node && ASSET_PATH=https://cdn.conversejs.org/$(VERSION)/dist/ make dist && make doc
cd .. && git pull && make node && ASSET_PATH=https://cdn.conversejs.org/dist/ make dist && make doc cd .. && git pull && make node && ASSET_PATH=https://cdn.conversejs.org/dist/ make dist && make doc
@ -157,6 +156,9 @@ devserver: node_modules
######################################################################## ########################################################################
## Builds ## Builds
dist/converse-no-dependencies.js: src webpack/webpack.common.js webpack/webpack.nodeps.js @converse/headless node_modules
npm run nodeps
dist/converse.js:: node_modules dist/converse.js:: node_modules
npm run build npm run build
@ -203,7 +205,16 @@ src/headless/dist/converse-headless.min.js: src webpack/webpack.common.js node_m
dist:: node_modules src/* | dist/website.css dist/website.min.css dist:: node_modules src/* | dist/website.css dist/website.min.css
npm run headless npm run headless
npm run build # Ideally this should just be `npm run build`.
# The additional steps are necessary to properly generate JSON chunk files
# from the .po files. The nodeps config uses preset-env with IE11.
# Somehow this is necessary.
npm run nodeps
$(eval TMPD := $(shell mktemp -d))
mv dist/locales $(TMPD) && \
npm run build && \
mv $(TMPD)/locales/*-po.js dist/locales/ && \
rm -rf $(TMPD)
.PHONY: install .PHONY: install
install:: dist install:: dist

17
README.chapril.md Normal file
View File

@ -0,0 +1,17 @@
# Construire une version Chapril de ConverseJS
```
cd .../conversejs
# La première fois, installer nvm (attention, ça va modifier le .bashrc, entre autres choses)
make nvm
export V=7.0.4
git rebase v${V?}
# [... Résoudre les conflits]
git checkout -b v${V?}-chapril
nvm install
make dist
# [... Tester les livrables présents dans dist/, et si tout est ok :]
make version VERSION=${V?}-chapril
rsync -av dist/ chapril-xmpp:/var/www/xmpp.chapril.org/public_html/dist-custom-chapril-${V?}/
```

View File

@ -1,18 +1,18 @@
# Release checklist # Release checklist
1. Check that weblate translations are all merged in 1. Merge weblate translations: https://hosted.weblate.org/projects/conversejs/translations/#repository
2. Run `make check` to check that all tests pass. 2. Run `make check` to check that all tests pass.
3. Run `make release VERSION=10.1.4` 3. Run `make version VERSION=10.1.6`
4. Do a `git diff` to check if things look sane. 4. Do a `git diff` to check if things look sane.
5. Do a quick manual test with the `dist` files (via `index.html`) 5. Do a quick manual test with the `dist` files (via `index.html`)
6. `git commit -am "Release 10.1.4"` 6. `git commit -am "Release 10.1.6"`
7. `git tag -s v10.1.4 -m "Release 10.1.4"` 7. `git tag -s v10.1.6 -m "Release 10.1.6"`
8. `git push && git push origin v10.1.4` 8. `git push && git push origin v10.1.6`
9. `make publish BRANCH=v10.1.4` 9. `make publish BRANCH=v10.1.6`
10. Update release page on Github 10. Update release page on Github
* Upload tar files * Upload tar files
11. Update https://conversejs.org 11. Update https://conversejs.org
* `cd /home/conversejs/converse.js` * `cd /home/conversejs/converse.js`
* `make deploy VERSION=10.1.4` * `make deploy VERSION=10.1.6`
12. Update the repository on weblate 12. Update the repository on weblate
13. Decide on next release number and run `make postrelease VERSION=10.1.5` 13. Decide on next release number and run `make postrelease VERSION=10.1.7`

View File

@ -28,6 +28,7 @@
}); });
converse.initialize({ converse.initialize({
i18n: 'af',
theme: 'dracula', theme: 'dracula',
auto_away: 300, auto_away: 300,
enable_smacks: true, enable_smacks: true,
@ -39,8 +40,8 @@
muc_show_logs_before_join: true, muc_show_logs_before_join: true,
notify_all_room_messages: ['discuss@conference.conversejs.org'], notify_all_room_messages: ['discuss@conference.conversejs.org'],
view_mode: 'fullscreen', view_mode: 'fullscreen',
websocket_url: 'wss://conversejs.org/xmpp-websocket', // websocket_url: 'wss://conversejs.org/xmpp-websocket',
// websocket_url: 'ws://chat.example.org:5380/xmpp-websocket', websocket_url: 'ws://chat.example.org:5380/xmpp-websocket',
whitelisted_plugins: ['converse-debug'], whitelisted_plugins: ['converse-debug'],
// connection_options: { worker: '/dist/shared-connection-worker.js' } // connection_options: { worker: '/dist/shared-connection-worker.js' }
}); });

View File

@ -48,9 +48,9 @@ copyright = u'2018, JC Brand'
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = '10.1.4' version = '10.1.6'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '10.1.4' release = '10.1.6'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

View File

@ -56,16 +56,16 @@ might break when a new backwards-incompatible version of Converse is released.
To load a specific version of Converse you can put the version in the URL: To load a specific version of Converse you can put the version in the URL:
* https://cdn.conversejs.org/10.1.4/dist/converse.min.js * https://cdn.conversejs.org/10.1.6/dist/converse.min.js
* https://cdn.conversejs.org/10.1.4/dist/converse.min.css * https://cdn.conversejs.org/10.1.6/dist/converse.min.css
You can include these two URLs inside the *<head>* element of your website You can include these two URLs inside the *<head>* element of your website
via the *script* and *link* tags: via the *script* and *link* tags:
.. code-block:: html .. code-block:: html
<link rel="stylesheet" type="text/css" media="screen" href="https://cdn.conversejs.org/10.1.4/dist/converse.min.css"> <link rel="stylesheet" type="text/css" media="screen" href="https://cdn.conversejs.org/10.1.6/dist/converse.min.css">
<script src="https://cdn.conversejs.org/10.1.4/dist/converse.min.js" charset="utf-8"></script> <script src="https://cdn.conversejs.org/10.1.6/dist/converse.min.js" charset="utf-8"></script>
Option 2: Download the builds from Github Option 2: Download the builds from Github

View File

@ -240,7 +240,7 @@
<div class="sponsors"> <div class="sponsors">
<h2>Converse is supported by:</h2> <h2>Converse is supported by:</h2>
<ul > <ul >
<li><a href="https://bairesdev.com/sponsoring-open-source-projects/?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 10em" src="/media/logos/bairesdev-primary.png" alt="BairesDev"></a></li> <li><a href="https://bairesdev.com/sponsoring-open-source-projects/?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 13em" src="/media/logos/bairesdev-primary.png" alt="BairesDev"></a></li>
<li><a href="https://blokt.com?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 12em" src="/logo/blokt.png" alt="Blokt Crypto & Privacy"></a></li> <li><a href="https://blokt.com?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 12em" src="/logo/blokt.png" alt="Blokt Crypto & Privacy"></a></li>
<li><a href="https://primesound.org/?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 10em" src="/media/logos/primesound.png" alt="Prime Sound"></a></li> <li><a href="https://primesound.org/?utm_source=conversejs" target="_blank" rel="noopener"><img style="width: 10em" src="/media/logos/primesound.png" alt="Prime Sound"></a></li>
<li><a href="https://www.keycdn.com?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 3em" src="/logo/keycdn.svg" alt="KeyCDN"></a></li> <li><a href="https://www.keycdn.com?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 3em" src="/logo/keycdn.svg" alt="KeyCDN"></a></li>

View File

@ -11,17 +11,17 @@
<!-- These files are NOT needed when using converse.js in your own project. --> <!-- These files are NOT needed when using converse.js in your own project. -->
<link rel="shortcut icon" type="image/ico" href="images/favicon.ico"/> <link rel="shortcut icon" type="image/ico" href="images/favicon.ico"/>
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/10.1.4/css/font-awesome.min.css" /> <link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/10.1.6/css/font-awesome.min.css" />
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/10.1.4/css/website.min.css" /> <link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/10.1.6/css/website.min.css" />
<noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript> <noscript><p><img src="//stats.opkode.com/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
<script type="text/javascript" src="/src/website.js"></script> <script type="text/javascript" src="/src/website.js"></script>
<script type="text/javascript" src="analytics.js"></script> <script type="text/javascript" src="analytics.js"></script>
<!-- *********************************************************************** --> <!-- *********************************************************************** -->
<![if gte IE 11]> <![if gte IE 11]>
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/10.1.4/css/converse.min.css" /> <link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/10.1.6/css/converse.min.css" />
<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script> <script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>
<script src="https://cdn.conversejs.org/10.1.4/dist/converse.min.js"></script> <script src="https://cdn.conversejs.org/10.1.6/dist/converse.min.js"></script>
<![endif]> <![endif]>
</head> </head>
@ -66,7 +66,7 @@
<table id="jslicense-labels1" style="width: 100%"> <table id="jslicense-labels1" style="width: 100%">
<tr> <tr>
<td> <td>
<a href="https://cdn.conversejs.org/10.1.4/dist/converse.min.js">converse.min.js</a> <a href="https://cdn.conversejs.org/10.1.6/dist/converse.min.js">converse.min.js</a>
</td> </td>
<td> <td>
<a href="https://www.mozilla.org/en-US/MPL/2.0/">MPL-2.0</a> <a href="https://www.mozilla.org/en-US/MPL/2.0/">MPL-2.0</a>

View File

@ -1,20 +1,34 @@
<svg class="converse-svg-logo" <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" id="svg108" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"
xmlns:svg="http://www.w3.org/2000/svg" xml:space="preserve" version="1.1"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 376 311" height="20%" width="10rem"
xmlns:xlink="http://www.w3.org/1999/xlink" sodipodi:docname="chapril-logo.svg" inkscape:version="0.92.1 r15371">
viewBox="0 0 364 364"> <sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="640" inkscape:window-height="480" id="namedview16" showgrid="false" inkscape:zoom="0.75884244" inkscape:cx="188" inkscape:cy="155.5" inkscape:window-x="0" inkscape:window-y="24" inkscape:window-maximized="0" inkscape:current-layer="svg108"/>
<title>Converse</title> <metadata id="metadata114">
<g class="cls-1" id="g904"> <rdf:RDF>
<g data-name="Layer 2"> <cc:Work rdf:about="">
<circle cx="180" cy="180" r="170" stroke="black" stroke-width="3" fill="white"/> <dc:format>image/svg+xml</dc:format>
<g data-name="Layer 7"> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<path <dc:title/>
class="cls-3" <cc:license rdf:resource="GFDL version 1.3 ou ultérieure, Creative Commons By Sa version 2.0 ou ultérieure, Licence Art Libre version 1.3 ou ultérieure"/>
d="M221.46,103.71c0,18.83-29.36,18.83-29.12,0C192.1,84.88,221.46,84.88,221.46,103.71Z" /> <dc:creator>
<path <cc:Agent>
class="cls-4" <dc:title>Antoine BARDELLI</dc:title>
d="M179.9,4.15A175.48,175.48,0,1,0,355.38,179.63,175.48,175.48,0,0,0,179.9,4.15Zm-40.79,264.5c-.23-17.82,27.58-17.82,27.58,0S138.88,286.48,139.11,268.65ZM218.6,168.24A79.65,79.65,0,0,1,205.15,174a12.76,12.76,0,0,0-6.29,4.65L167.54,222a1.36,1.36,0,0,1-2.46-.8v-35.8a2.58,2.58,0,0,0-3.06-2.53c-15.43,3-30.23,7.7-42.73,19.94-38.8,38-29.42,105.69,16.09,133.16a162.25,162.25,0,0,1-91.47-67.27C-3.86,182.26,34.5,47.25,138.37,25.66c46.89-9.75,118.25,5.16,123.73,62.83C265.15,120.64,246.56,152.89,218.6,168.24Z" /> </cc:Agent>
</g> </dc:creator>
</g> </cc:Work>
</g> </rdf:RDF>
</svg> </metadata>
<defs id="defs112"/>
<g id="g250" style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" transform="translate(4.6079614e-7,-4.4571451e-6)">
<path id="path124" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 96.70711,209.69029 c -2.742,1.114 -5.399,1.8 -7.885,2.057 -0.771,0.085 -1.629,0.171 -2.4,0.171 -2.571,0 -5.314,-0.428 -8.228,-1.286 -2.486,-0.857 -4.628,-2.314 -6.514,-4.371 -1.886,-1.8 -3.343,-3.942 -4.371,-6.428 -0.943,-2.486 -1.457,-5.057 -1.543,-7.714 0,-0.086 0,-0.257 0,-0.343 0,-2.485 0.514,-4.971 1.543,-7.371 1.028,-2.314 2.485,-4.457 4.371,-6.428 1.886,-2.057 4.028,-3.514 6.514,-4.371 2.828,-1.029 5.571,-1.543 8.142,-1.543 0.257,0 0.6,0 0.857,0 3.686,0.171 6.857,1.028 9.686,2.657 -0.086,1.457 -0.343,3.514 -0.6,6.343 -2.743,-1.372 -5.4,-2.143 -7.971,-2.315 -1.972,-0.171 -3.943,0.086 -6,0.772 -1.629,0.514 -3.171,1.457 -4.457,2.914 -1.286,1.371 -2.228,2.828 -2.914,4.457 -0.772,1.628 -1.114,3.342 -1.114,5.142 0.085,1.886 0.428,3.6 1.114,5.229 0.686,1.714 1.628,3.171 2.914,4.457 1.286,1.285 2.828,2.228 4.457,2.914 2.486,0.685 4.543,1.028 6.343,1.028 3.342,-0.343 5.999,-1.2 8.056,-2.657 0,1.457 0,3.686 0,6.686 z"/>
<path id="path126" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 137.33411,184.91929 c 0,1.8 0,3.515 0,5.314 0,2.657 0,5.4 -0.086,8.057 0,4.457 0,8.743 0,12.771 -1.714,0 -4.285,0 -7.799,0 0,-3.857 0,-11.571 0.085,-23.142 0.086,-1.114 -0.171,-2.228 -0.6,-3.257 -0.428,-1.028 -1.028,-1.971 -1.8,-2.742 -0.942,-0.943 -2.142,-1.715 -3.599,-2.143 -1.029,-0.257 -2.229,-0.429 -3.6,-0.343 -1.115,0.086 -2.229,0.343 -3.257,0.686 -1.029,0.428 -2.143,1.028 -3.343,1.8 -0.6,0.6 -1.029,1.2 -1.457,1.8 v 27.341 h -8.057 v -62.997 h 8.057 v 29.313 c 0.943,-1.114 1.8,-1.971 2.571,-2.486 1.629,-0.942 3,-1.542 4.2,-1.885 1.971,-0.429 3.771,-0.6 5.571,-0.6 2.143,0.085 3.943,0.343 5.4,0.943 1.543,0.6 2.914,1.542 4.028,2.742 2.4,2.572 3.6,5.486 3.686,8.828 z"/>
<path id="path128" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 169.38911,146.86429 c 4.714,10.714 14.228,32.056 28.37,64.111 -1.371,0 -4.114,0 -8.313,0 -1.286,-2.657 -3.772,-7.971 -7.543,-15.942 -4.028,0 -12.085,0 -24.17,0 -1.114,2.657 -3.514,7.971 -7.028,15.942 -1.457,0 -4.2,0 -8.4,0 4.543,-10.713 13.542,-32.055 27.084,-64.111 z m 9.171,40.884 c -1.457,-3.686 -4.542,-10.885 -9.085,-21.77 -1.457,3.599 -4.285,10.885 -8.571,21.77 3,0 8.828,0 17.656,0 z"/>
<path id="path130" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 212.15911,199.83329 c 0.257,0.429 0.6,0.771 0.857,1.114 1.114,1.457 2.657,2.743 4.457,3.686 1.457,0.685 3.085,1.028 4.8,1.028 0.085,0 0.257,0 0.428,0 1.8,0.086 3.514,-0.257 5.143,-1.028 1.628,-0.6 3.171,-1.629 4.457,-2.914 1.285,-1.286 2.228,-2.743 2.914,-4.457 0.685,-1.543 1.028,-3.343 1.028,-5.314 0.086,-1.715 -0.257,-3.429 -1.028,-5.057 -0.6,-1.629 -1.629,-3.171 -2.914,-4.457 -1.286,-1.286 -2.743,-2.229 -4.457,-2.914 -1.115,-0.515 -2.572,-0.772 -4.2,-0.772 -0.172,0 -0.343,0 -0.429,0 -2.657,0.086 -4.714,0.429 -5.999,1.2 -3.429,1.8 -5.143,3.857 -5.143,6.171 0,3 0,7.629 0.086,13.714 z m 0,8.314 c -0.086,3.343 -0.086,10.028 -0.086,20.056 -1.286,0 -4.028,0 -8.057,0 v -54.769 c 2.657,0 5.4,0 8.057,0 0.086,1.286 0.086,2.4 0.086,3.257 0.857,-1.114 2.314,-2.142 4.457,-3.085 2.4,-1.029 4.971,-1.543 7.714,-1.543 2.657,0 5.228,0.514 7.628,1.543 2.485,1.028 4.714,2.485 6.514,4.371 1.971,1.886 3.428,4.028 4.371,6.428 1.028,2.486 1.543,4.971 1.543,7.543 0,0.085 0,0.085 0,0.171 0,2.657 -0.515,5.228 -1.543,7.714 -1.029,2.486 -2.486,4.628 -4.371,6.428 -1.886,1.972 -4.029,3.429 -6.514,4.371 -2.486,1.029 -5.057,1.543 -7.628,1.543 -2.657,-0.085 -5.229,-0.6 -7.714,-1.543 -1.372,-0.514 -2.829,-1.371 -4.457,-2.485 z"/>
<path id="path132" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 271.04211,180.46329 c 0,-0.086 -0.686,-0.172 -2.143,-0.429 -2.743,-0.086 -5.228,0.857 -7.371,2.828 -0.857,0.772 -1.543,1.886 -2.057,3.343 -0.343,1.371 -0.515,2.829 -0.6,4.457 0,4.543 0,11.399 0,20.399 -1.286,0 -3.943,0 -7.971,0 0,-6.257 0,-18.856 -0.086,-37.627 1.286,0 3.943,0 7.8,0 0.085,0.772 0.085,2.4 0.085,4.8 0,0.514 0,1.543 -0.085,3.171 1.028,-4.199 3.085,-6.856 6.085,-7.971 1.2,-0.343 2.4,-0.514 3.686,-0.514 0.857,-0.086 1.714,0 2.657,0.171 0,1.629 0,4.115 0,7.372 z"/>
<path id="path134" style="clip-rule:evenodd;fill:#005184;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 277.47011,163.23529 c 0,-1.372 0.514,-2.4 1.457,-3.171 0.943,-0.772 1.971,-1.2 3.085,-1.2 0.086,0 0.172,0 0.258,0 1.114,0 2.057,0.342 2.999,1.028 0.943,0.771 1.372,1.8 1.372,3.257 0,1.457 -0.429,2.571 -1.372,3.428 -0.942,0.858 -2.057,1.286 -3.257,1.286 -1.114,0 -2.142,-0.428 -3.085,-1.2 -0.943,-0.771 -1.457,-1.971 -1.457,-3.428 z"/>
<path style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" id="path136" d="m 278.15611,173.34929 c 1.371,0 4.028,0 8.056,0 0,6.342 0,18.942 0,37.883 -1.285,0 -3.942,0 -7.885,0 0,-6.256 -0.086,-18.941 -0.171,-37.883 z"/>
<path id="path138" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 295.55511,146.26429 v 64.797 c 1.285,0 3.942,0 7.885,0 0,-10.799 0,-32.398 0,-64.797 -1.286,0 -3.943,0 -7.885,0 z"/>
<path id="path144" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 79.90511,45.008286 c 0.902,0.305 0.903,0.306 1.74,0.76 0,0 2.36,1.6 3.541,2.399 16.192,11.056 46.905,36.807 46.905,36.807 l -0.62,0.933 c 0,0 -30.962,-17.269 -47.812,-25.837 -0.154,2.104 -0.309,4.208 -0.465,6.312 l -0.126,1.689 c -0.635,7.993 -1.295,15.97 -2,23.945 l -0.096,1.076 c -0.824,8.583004 -1.124,17.369004 -3.069,25.573004 -1.802,7.601 -10.27,13.477 -15.485,20.114 -10.856,13.816 -19.361,29.582 -21.64,47.603 -2.579,20.389 5.773,40.853 21.062,55.815 5.92,5.794 12.534,10.853 19.323,15.617 l -3.768,5.852 c -20.581,-12.139 -40.182,-28.618 -47.181,-51.981 -6.615,-22.081 -1.608,-47.917 10.144,-67.278 6.689,-11.02 14.834,-21.098 23.413,-30.201 0,0 0.585,-2.521 0.874,-4.27 3.14,-19.016004 5.383,-38.057004 7.92,-57.227004 l 0.274,-2.074 0.28,-1.686 c 0.307,-0.8 0.337,-1.033 0.841,-1.737 1.119,-1.562 2.062,-2.818 5.945,-2.204 z"/>
<path id="path146" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 300.65411,44.858286 c 2.74,0.486 2.778,0.936 3.448,1.587 2.555,2.484 2.191,7.238 2.75,11.471 2.467,18.612 4.172,37.353 7.871,55.935004 0,0 3.607,4.013 6.264,7.099 11.064,12.849 21.019,26.411 26.284,43.975 6.27,20.92 3.585,41.82 -7.633,60.315 -9.349,15.414 -24.268,26.668 -39.964,35.962 l -0.593,-1.853 c 17.279,-12.08 34.133,-26.972 39.318,-48.24 3.677,-15.083 -0.809,-32.515 -6.571,-47.292 -5.094,-13.065 -14.589,-24.209 -23.233,-34.394 -1.789,-2.107 -3.603,-4.192 -5.472,-6.229 0,0 -2.204,-3.069 -2.806,-6.739 -2.582,-15.749 -3.416,-31.540004 -4.699,-47.326004 0,0 -0.34,-4.424 -0.589,-7.754 l -0.098,-1.322 -30.582,18.428 -15.221,9.11 -0.801,0.477 -3.955,-6.151 0.767,-0.531 14.605,-10.067 37.28,-25.534 c 0,0 1.172,-0.939 3.63,-0.927 z m 14.362,70.312004 c 0.178,0.639 -0.049,-0.186 0,0 z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -1,108 +1,46 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg <svg
xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#" xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
class="converse-svg-logo" id="chapril-logo"
viewBox="0 0 364 364" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"
version="1.1" class="converse-svg-logo"
id="svg13" xml:space="preserve" version="1.1"
sodipodi:docname="conversejs-with-byline.svg" viewBox="0 0 376 311" height="20%" width="6rem"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"> sodipodi:docname="chapril-logo.svg" inkscape:version="0.92.1 r15371">
<metadata <sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="640" inkscape:window-height="480" id="namedview16" showgrid="false" inkscape:zoom="0.75884244" inkscape:cx="188" inkscape:cy="155.5" inkscape:window-x="0" inkscape:window-y="24" inkscape:window-maximized="0" inkscape:current-layer="svg108"/>
id="metadata19"> <metadata id="metadata114">
<rdf:RDF> <rdf:RDF>
<cc:Work <cc:Work rdf:about="">
rdf:about="">
<dc:format>image/svg+xml</dc:format> <dc:format>image/svg+xml</dc:format>
<dc:type <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title/>
<dc:title>Converse</dc:title> <cc:license rdf:resource="GFDL version 1.3 ou ultérieure, Creative Commons By Sa version 2.0 ou ultérieure, Licence Art Libre version 1.3 ou ultérieure"/>
<dc:creator>
<cc:Agent>
<dc:title>Antoine BARDELLI</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work> </cc:Work>
</rdf:RDF> </rdf:RDF>
</metadata> </metadata>
<defs <defs id="defs112"/>
id="defs17"> <g id="g250" style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" transform="translate(4.6079614e-7,-4.4571451e-6)">
<inkscape:perspective <path id="path124" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 96.70711,209.69029 c -2.742,1.114 -5.399,1.8 -7.885,2.057 -0.771,0.085 -1.629,0.171 -2.4,0.171 -2.571,0 -5.314,-0.428 -8.228,-1.286 -2.486,-0.857 -4.628,-2.314 -6.514,-4.371 -1.886,-1.8 -3.343,-3.942 -4.371,-6.428 -0.943,-2.486 -1.457,-5.057 -1.543,-7.714 0,-0.086 0,-0.257 0,-0.343 0,-2.485 0.514,-4.971 1.543,-7.371 1.028,-2.314 2.485,-4.457 4.371,-6.428 1.886,-2.057 4.028,-3.514 6.514,-4.371 2.828,-1.029 5.571,-1.543 8.142,-1.543 0.257,0 0.6,0 0.857,0 3.686,0.171 6.857,1.028 9.686,2.657 -0.086,1.457 -0.343,3.514 -0.6,6.343 -2.743,-1.372 -5.4,-2.143 -7.971,-2.315 -1.972,-0.171 -3.943,0.086 -6,0.772 -1.629,0.514 -3.171,1.457 -4.457,2.914 -1.286,1.371 -2.228,2.828 -2.914,4.457 -0.772,1.628 -1.114,3.342 -1.114,5.142 0.085,1.886 0.428,3.6 1.114,5.229 0.686,1.714 1.628,3.171 2.914,4.457 1.286,1.285 2.828,2.228 4.457,2.914 2.486,0.685 4.543,1.028 6.343,1.028 3.342,-0.343 5.999,-1.2 8.056,-2.657 0,1.457 0,3.686 0,6.686 z"/>
sodipodi:type="inkscape:persp3d" <path id="path126" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 137.33411,184.91929 c 0,1.8 0,3.515 0,5.314 0,2.657 0,5.4 -0.086,8.057 0,4.457 0,8.743 0,12.771 -1.714,0 -4.285,0 -7.799,0 0,-3.857 0,-11.571 0.085,-23.142 0.086,-1.114 -0.171,-2.228 -0.6,-3.257 -0.428,-1.028 -1.028,-1.971 -1.8,-2.742 -0.942,-0.943 -2.142,-1.715 -3.599,-2.143 -1.029,-0.257 -2.229,-0.429 -3.6,-0.343 -1.115,0.086 -2.229,0.343 -3.257,0.686 -1.029,0.428 -2.143,1.028 -3.343,1.8 -0.6,0.6 -1.029,1.2 -1.457,1.8 v 27.341 h -8.057 v -62.997 h 8.057 v 29.313 c 0.943,-1.114 1.8,-1.971 2.571,-2.486 1.629,-0.942 3,-1.542 4.2,-1.885 1.971,-0.429 3.771,-0.6 5.571,-0.6 2.143,0.085 3.943,0.343 5.4,0.943 1.543,0.6 2.914,1.542 4.028,2.742 2.4,2.572 3.6,5.486 3.686,8.828 z"/>
inkscape:vp_x="0 : 182 : 1" <path id="path128" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 169.38911,146.86429 c 4.714,10.714 14.228,32.056 28.37,64.111 -1.371,0 -4.114,0 -8.313,0 -1.286,-2.657 -3.772,-7.971 -7.543,-15.942 -4.028,0 -12.085,0 -24.17,0 -1.114,2.657 -3.514,7.971 -7.028,15.942 -1.457,0 -4.2,0 -8.4,0 4.543,-10.713 13.542,-32.055 27.084,-64.111 z m 9.171,40.884 c -1.457,-3.686 -4.542,-10.885 -9.085,-21.77 -1.457,3.599 -4.285,10.885 -8.571,21.77 3,0 8.828,0 17.656,0 z"/>
inkscape:vp_y="0 : 1000 : 0" <path id="path130" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 212.15911,199.83329 c 0.257,0.429 0.6,0.771 0.857,1.114 1.114,1.457 2.657,2.743 4.457,3.686 1.457,0.685 3.085,1.028 4.8,1.028 0.085,0 0.257,0 0.428,0 1.8,0.086 3.514,-0.257 5.143,-1.028 1.628,-0.6 3.171,-1.629 4.457,-2.914 1.285,-1.286 2.228,-2.743 2.914,-4.457 0.685,-1.543 1.028,-3.343 1.028,-5.314 0.086,-1.715 -0.257,-3.429 -1.028,-5.057 -0.6,-1.629 -1.629,-3.171 -2.914,-4.457 -1.286,-1.286 -2.743,-2.229 -4.457,-2.914 -1.115,-0.515 -2.572,-0.772 -4.2,-0.772 -0.172,0 -0.343,0 -0.429,0 -2.657,0.086 -4.714,0.429 -5.999,1.2 -3.429,1.8 -5.143,3.857 -5.143,6.171 0,3 0,7.629 0.086,13.714 z m 0,8.314 c -0.086,3.343 -0.086,10.028 -0.086,20.056 -1.286,0 -4.028,0 -8.057,0 v -54.769 c 2.657,0 5.4,0 8.057,0 0.086,1.286 0.086,2.4 0.086,3.257 0.857,-1.114 2.314,-2.142 4.457,-3.085 2.4,-1.029 4.971,-1.543 7.714,-1.543 2.657,0 5.228,0.514 7.628,1.543 2.485,1.028 4.714,2.485 6.514,4.371 1.971,1.886 3.428,4.028 4.371,6.428 1.028,2.486 1.543,4.971 1.543,7.543 0,0.085 0,0.085 0,0.171 0,2.657 -0.515,5.228 -1.543,7.714 -1.029,2.486 -2.486,4.628 -4.371,6.428 -1.886,1.972 -4.029,3.429 -6.514,4.371 -2.486,1.029 -5.057,1.543 -7.628,1.543 -2.657,-0.085 -5.229,-0.6 -7.714,-1.543 -1.372,-0.514 -2.829,-1.371 -4.457,-2.485 z"/>
inkscape:vp_z="364 : 182 : 1" <path id="path132" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 271.04211,180.46329 c 0,-0.086 -0.686,-0.172 -2.143,-0.429 -2.743,-0.086 -5.228,0.857 -7.371,2.828 -0.857,0.772 -1.543,1.886 -2.057,3.343 -0.343,1.371 -0.515,2.829 -0.6,4.457 0,4.543 0,11.399 0,20.399 -1.286,0 -3.943,0 -7.971,0 0,-6.257 0,-18.856 -0.086,-37.627 1.286,0 3.943,0 7.8,0 0.085,0.772 0.085,2.4 0.085,4.8 0,0.514 0,1.543 -0.085,3.171 1.028,-4.199 3.085,-6.856 6.085,-7.971 1.2,-0.343 2.4,-0.514 3.686,-0.514 0.857,-0.086 1.714,0 2.657,0.171 0,1.629 0,4.115 0,7.372 z"/>
inkscape:persp3d-origin="182 : 121.33333 : 1" <path id="path134" style="clip-rule:evenodd;fill:#005184;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 277.47011,163.23529 c 0,-1.372 0.514,-2.4 1.457,-3.171 0.943,-0.772 1.971,-1.2 3.085,-1.2 0.086,0 0.172,0 0.258,0 1.114,0 2.057,0.342 2.999,1.028 0.943,0.771 1.372,1.8 1.372,3.257 0,1.457 -0.429,2.571 -1.372,3.428 -0.942,0.858 -2.057,1.286 -3.257,1.286 -1.114,0 -2.142,-0.428 -3.085,-1.2 -0.943,-0.771 -1.457,-1.971 -1.457,-3.428 z"/>
id="perspective2147" /> <path style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" id="path136" d="m 278.15611,173.34929 c 1.371,0 4.028,0 8.056,0 0,6.342 0,18.942 0,37.883 -1.285,0 -3.942,0 -7.885,0 0,-6.256 -0.086,-18.941 -0.171,-37.883 z"/>
</defs> <path id="path138" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 295.55511,146.26429 v 64.797 c 1.285,0 3.942,0 7.885,0 0,-10.799 0,-32.398 0,-64.797 -1.286,0 -3.943,0 -7.885,0 z"/>
<sodipodi:namedview <path id="path144" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 79.90511,45.008286 c 0.902,0.305 0.903,0.306 1.74,0.76 0,0 2.36,1.6 3.541,2.399 16.192,11.056 46.905,36.807 46.905,36.807 l -0.62,0.933 c 0,0 -30.962,-17.269 -47.812,-25.837 -0.154,2.104 -0.309,4.208 -0.465,6.312 l -0.126,1.689 c -0.635,7.993 -1.295,15.97 -2,23.945 l -0.096,1.076 c -0.824,8.583004 -1.124,17.369004 -3.069,25.573004 -1.802,7.601 -10.27,13.477 -15.485,20.114 -10.856,13.816 -19.361,29.582 -21.64,47.603 -2.579,20.389 5.773,40.853 21.062,55.815 5.92,5.794 12.534,10.853 19.323,15.617 l -3.768,5.852 c -20.581,-12.139 -40.182,-28.618 -47.181,-51.981 -6.615,-22.081 -1.608,-47.917 10.144,-67.278 6.689,-11.02 14.834,-21.098 23.413,-30.201 0,0 0.585,-2.521 0.874,-4.27 3.14,-19.016004 5.383,-38.057004 7.92,-57.227004 l 0.274,-2.074 0.28,-1.686 c 0.307,-0.8 0.337,-1.033 0.841,-1.737 1.119,-1.562 2.062,-2.818 5.945,-2.204 z"/>
pagecolor="#ffffff" <path id="path146" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 300.65411,44.858286 c 2.74,0.486 2.778,0.936 3.448,1.587 2.555,2.484 2.191,7.238 2.75,11.471 2.467,18.612 4.172,37.353 7.871,55.935004 0,0 3.607,4.013 6.264,7.099 11.064,12.849 21.019,26.411 26.284,43.975 6.27,20.92 3.585,41.82 -7.633,60.315 -9.349,15.414 -24.268,26.668 -39.964,35.962 l -0.593,-1.853 c 17.279,-12.08 34.133,-26.972 39.318,-48.24 3.677,-15.083 -0.809,-32.515 -6.571,-47.292 -5.094,-13.065 -14.589,-24.209 -23.233,-34.394 -1.789,-2.107 -3.603,-4.192 -5.472,-6.229 0,0 -2.204,-3.069 -2.806,-6.739 -2.582,-15.749 -3.416,-31.540004 -4.699,-47.326004 0,0 -0.34,-4.424 -0.589,-7.754 l -0.098,-1.322 -30.582,18.428 -15.221,9.11 -0.801,0.477 -3.955,-6.151 0.767,-0.531 14.605,-10.067 37.28,-25.534 c 0,0 1.172,-0.939 3.63,-0.927 z m 14.362,70.312004 c 0.178,0.639 -0.049,-0.186 0,0 z"/>
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1434"
inkscape:window-height="951"
id="namedview15"
showgrid="false"
inkscape:zoom="1.8338154"
inkscape:cx="225.17086"
inkscape:cy="243.79827"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg13" />
<title
id="title2">Converse</title>
<g
class="cls-1"
id="g904"
transform="matrix(0.2441072,0,0,0.2441072,12.20969,55.55023)">
<g
data-name="Layer 2"
id="g10">
<g
data-name="Layer 7"
id="g8">
<path
class="cls-3"
d="m 221.46,103.71 c 0,18.83 -29.36,18.83 -29.12,0 -0.24,-18.83 29.12,-18.83 29.12,0 z"
id="path4"
inkscape:connector-curvature="0" />
<path
class="cls-4"
d="M 179.9,4.15 C 108.92504,4.15 44.938239,46.904566 17.778836,112.4757 -9.3805118,178.0467 5.6365472,253.52014 55.823205,303.70679 106.00986,353.89345 181.4833,368.91051 247.0543,341.75116 312.62543,314.59176 355.38,250.60496 355.38,179.63 355.38,82.715072 276.81493,4.15 179.9,4.15 Z m -40.79,264.5 c -0.23,-17.82 27.58,-17.82 27.58,0 0,17.82 -27.81,17.83 -27.58,0 z M 218.6,168.24 c -4.29711,2.32859 -8.79944,4.25673 -13.45,5.76 -2.53177,0.85328 -12.23498,3.26952 -13.79313,5.4398 C 180.90809,189.252 165.08,221.2 165.08,221.2 v -35.8 c -0.003,-1.6153 -1.4729,-2.83052 -3.06,-2.53 -15.43,3 -30.23,7.7 -42.73,19.94 -38.8,38 -29.025098,103.71549 16.4849,131.18549 C 98.17801,323.32071 65.725789,295.74404 44.332966,263.03587 -3.4370336,176.59587 35.058475,51.159326 138.92848,29.569326 185.81848,19.819326 256.62,30.82 262.1,88.49 c 3.05,32.15 -15.54,64.4 -43.5,79.75 z"
id="path6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssscsccccccccccccc" />
</g>
</g>
</g> </g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:50.63063431px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.10960984px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="110.04511"
y="98.826035"
id="text861"><tspan
sodipodi:role="line"
id="tspan859"
x="110.04511"
y="98.826035"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:50.63063431px;font-family:Baumans;-inkscape-font-specification:'Baumans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:2.10960984px">converse<tspan
style="fill:#a2a2a2;fill-opacity:1;stroke-width:2.10960984px"
id="tspan867">.js</tspan></tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.49652481px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.77068853px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="124.58434"
y="128.44286"
id="text865"><tspan
sodipodi:role="line"
id="tspan863"
x="124.58434"
y="128.44286"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.49652481px;font-family:Muli;-inkscape-font-specification:'Muli, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#484848;fill-opacity:1;stroke-width:0.77068853px">messaging freedom</tspan></text>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -2,7 +2,7 @@
"short_name": "Converse", "short_name": "Converse",
"name": "Converse Chat", "name": "Converse Chat",
"description": "Messaging Freedom", "description": "Messaging Freedom",
"version": "10.1.4", "version": "10.1.6",
"categories": ["social"], "categories": ["social"],
"icons": [ "icons": [
{ {

View File

@ -19,9 +19,9 @@
<script type="text/javascript" src="analytics.js"></script> <script type="text/javascript" src="analytics.js"></script>
<!-- *********************************************************************** --> <!-- *********************************************************************** -->
<link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/10.1.4/dist/converse.min.css" /> <link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/10.1.6/dist/converse.min.css" />
<script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script> <script src="https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js"></script>
<script src="https://cdn.conversejs.org/10.1.4/dist/converse.min.js"></script> <script src="https://cdn.conversejs.org/10.1.6/dist/converse.min.js"></script>
</head> </head>
<body id="page-top" data-spy="scroll" class="converse-website"> <body id="page-top" data-spy="scroll" class="converse-website">

20
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "converse.js", "name": "converse.js",
"version": "10.1.4", "version": "10.1.6",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "converse.js", "name": "converse.js",
"version": "10.1.4", "version": "10.1.6",
"license": "MPL-2.0", "license": "MPL-2.0",
"workspaces": [ "workspaces": [
"src/headless" "src/headless"
@ -20,6 +20,7 @@
"dayjs": "^1.11.8", "dayjs": "^1.11.8",
"dompurify": "^2.3.1", "dompurify": "^2.3.1",
"favico.js-slevomat": "^0.3.11", "favico.js-slevomat": "^0.3.11",
"gifuct-js": "^2.1.2",
"jed": "1.1.1", "jed": "1.1.1",
"lit": "^2.4.0", "lit": "^2.4.0",
"localforage-webextensionstorage-driver": "^3.0.0", "localforage-webextensionstorage-driver": "^3.0.0",
@ -5612,6 +5613,14 @@
"safe-buffer": "^5.1.1" "safe-buffer": "^5.1.1"
} }
}, },
"node_modules/gifuct-js": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/gifuct-js/-/gifuct-js-2.1.2.tgz",
"integrity": "sha512-rI2asw77u0mGgwhV3qA+OEgYqaDn5UNqgs+Bx0FGwSpuqfYn+Ir6RQY5ENNQ8SbIiG/m5gVa7CD5RriO4f4Lsg==",
"dependencies": {
"js-binary-schema-parser": "^2.0.3"
}
},
"node_modules/glob": { "node_modules/glob": {
"version": "7.2.3", "version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@ -6632,6 +6641,11 @@
"integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==", "integrity": "sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==",
"peer": true "peer": true
}, },
"node_modules/js-binary-schema-parser": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/js-binary-schema-parser/-/js-binary-schema-parser-2.0.3.tgz",
"integrity": "sha512-xezGJmOb4lk/M1ZZLTR/jaBHQ4gG/lqQnJqdIv4721DMggsa1bDVlHXNeHYogaIEHD9vCRv0fcL4hMA+Coarkg=="
},
"node_modules/js-tokens": { "node_modules/js-tokens": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@ -11235,7 +11249,7 @@
}, },
"src/headless": { "src/headless": {
"name": "@converse/headless", "name": "@converse/headless",
"version": "10.1.4", "version": "10.1.6",
"license": "MPL-2.0", "license": "MPL-2.0",
"dependencies": { "dependencies": {
"@converse/openpromise": "^0.0.1", "@converse/openpromise": "^0.0.1",

View File

@ -1,6 +1,6 @@
{ {
"name": "converse.js", "name": "converse.js",
"version": "10.1.4", "version": "10.1.6",
"description": "Browser based XMPP chat client", "description": "Browser based XMPP chat client",
"browser": "dist/converse.js", "browser": "dist/converse.js",
"module": "src/index.js", "module": "src/index.js",
@ -119,6 +119,7 @@
"dayjs": "^1.11.8", "dayjs": "^1.11.8",
"dompurify": "^2.3.1", "dompurify": "^2.3.1",
"favico.js-slevomat": "^0.3.11", "favico.js-slevomat": "^0.3.11",
"gifuct-js": "^2.1.2",
"jed": "1.1.1", "jed": "1.1.1",
"lit": "^2.4.0", "lit": "^2.4.0",
"localforage-webextensionstorage-driver": "^3.0.0", "localforage-webextensionstorage-driver": "^3.0.0",

View File

@ -1,6 +1,6 @@
{ {
"name": "@converse/headless", "name": "@converse/headless",
"version": "10.1.4", "version": "10.1.6",
"description": "Converse.js Headless build", "description": "Converse.js Headless build",
"author": "JC Brand <jc@opkode.com>", "author": "JC Brand <jc@opkode.com>",
"contributors": [ "contributors": [

View File

@ -1,7 +1,7 @@
import { Strophe } from 'strophe.js/src/strophe'; import { Strophe } from 'strophe.js/src/strophe';
export const BOSH_WAIT = 59; export const BOSH_WAIT = 59;
export const VERSION_NAME = "v10.1.4"; export const VERSION_NAME = "v10.1.6";
export const STATUS_WEIGHTS = { export const STATUS_WEIGHTS = {
offline: 6, offline: 6,

View File

@ -6,7 +6,7 @@
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Converse.js 10.1.4\n" "Project-Id-Version: Converse.js 10.1.5\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-25 11:01+0200\n" "POT-Creation-Date: 2023-06-25 11:01+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"

View File

@ -8,15 +8,15 @@ msgstr ""
"Project-Id-Version: Converse.js 0.4\n" "Project-Id-Version: Converse.js 0.4\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-23 10:10+0200\n" "POT-Creation-Date: 2023-06-23 10:10+0200\n"
"PO-Revision-Date: 2023-02-19 20:17+0000\n" "PO-Revision-Date: 2023-08-16 01:15+0000\n"
"Last-Translator: nautilusx <translate@disroot.org>\n" "Last-Translator: W L <wl@mailhole.de>\n"
"Language-Team: German <https://hosted.weblate.org/projects/conversejs/" "Language-Team: German <https://hosted.weblate.org/projects/conversejs/"
"translations/de/>\n" "translations/de/>\n"
"Language: de\n" "Language: de\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;t st\n"
"X-Generator: Weblate 4.16-dev\n" "X-Generator: Weblate 4.16-dev\n"
"domain: converse\n" "domain: converse\n"
"lang: de\n" "lang: de\n"
@ -1380,7 +1380,7 @@ msgstr "Benutzername"
#: dist/converse-no-dependencies.js:99532 #: dist/converse-no-dependencies.js:99532
msgid "user@domain" msgid "user@domain"
msgstr "user@domain" msgstr "nutzer@domain"
#: dist/converse-no-dependencies.js:99538 #: dist/converse-no-dependencies.js:99538
msgid "Disconnected" msgid "Disconnected"

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Converse.js 4.0.4\n" "Project-Id-Version: Converse.js 4.0.4\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-23 10:10+0200\n" "POT-Creation-Date: 2023-06-23 10:10+0200\n"
"PO-Revision-Date: 2023-02-19 05:39+0000\n" "PO-Revision-Date: 2023-06-29 05:51+0000\n"
"Last-Translator: \"josé m.\" <correoxm@disroot.org>\n" "Last-Translator: \"josé m.\" <correoxm@disroot.org>\n"
"Language-Team: Galician <https://hosted.weblate.org/projects/conversejs/" "Language-Team: Galician <https://hosted.weblate.org/projects/conversejs/"
"translations/gl/>\n" "translations/gl/>\n"
@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.16-dev\n" "X-Generator: Weblate 4.18.1\n"
#: dist/converse-no-dependencies.js:29951 #: dist/converse-no-dependencies.js:29951
msgid "The connection has dropped, attempting to reconnect." msgid "The connection has dropped, attempting to reconnect."
@ -714,9 +714,8 @@ msgid "Affiliation changed"
msgstr "Cambiou a afiliación" msgstr "Cambiou a afiliación"
#: dist/converse-no-dependencies.js:77005 #: dist/converse-no-dependencies.js:77005
#, fuzzy
msgid "role changed" msgid "role changed"
msgstr "Rol cambiado" msgstr "rol cambiado"
#: dist/converse-no-dependencies.js:77099 #: dist/converse-no-dependencies.js:77099
msgid "" msgid ""

View File

@ -5,53 +5,48 @@
* @description This is the internationalization module * @description This is the internationalization module
*/ */
import Jed from 'jed'; import Jed from 'jed';
import log from "@converse/headless/log.js"; import log from '@converse/headless/log.js';
import { _converse, api, converse, i18n } from '@converse/headless/core.js'; import { _converse, api, converse, i18n } from '@converse/headless/core.js';
const { dayjs } = converse.env; const { dayjs } = converse.env;
let jed_instance;
function detectLocale (library_check) { /**
/* Determine which locale is supported by the user's system as well * @private
* as by the relevant library (e.g. converse.js or dayjs). * @param { string } locale
* @param { Function } library_check - Returns a boolean indicating whether * @param { string[] } supported_locales
* the locale is supported. */
*/
let locale;
if (window.navigator.userLanguage) {
locale = isLocaleAvailable(window.navigator.userLanguage, library_check);
}
if (window.navigator.languages && !locale) {
for (let i=0; i<window.navigator.languages.length && !locale; i++) {
locale = isLocaleAvailable(window.navigator.languages[i], library_check);
}
}
if (window.navigator.browserLanguage && !locale) {
locale = isLocaleAvailable(window.navigator.browserLanguage, library_check);
}
if (window.navigator.language && !locale) {
locale = isLocaleAvailable(window.navigator.language, library_check);
}
if (window.navigator.systemLanguage && !locale) {
locale = isLocaleAvailable(window.navigator.systemLanguage, library_check);
}
return locale || 'en';
}
function isConverseLocale (locale, supported_locales) { function isConverseLocale (locale, supported_locales) {
return typeof locale === 'string' && supported_locales.includes(locale); return typeof locale === 'string' && supported_locales.includes(locale);
} }
/**
* Determines which locale is supported by the user's system as well
* as by the relevant library (e.g. converse.js or dayjs).
* @private
* @param { string } preferred_locale
* @param { Function } isSupportedByLibrary - Returns a boolean indicating whether
* the locale is supported.
* @returns { string }
*/
function getLocale (preferred_locale, isSupportedByLibrary) { function getLocale (preferred_locale, isSupportedByLibrary) {
if (typeof preferred_locale === 'string') { if (preferred_locale === 'en' || isSupportedByLibrary(preferred_locale)) {
if (preferred_locale === 'en' || isSupportedByLibrary(preferred_locale)) { return preferred_locale;
return preferred_locale;
}
} }
return detectLocale(isSupportedByLibrary) || 'en';
const { languages } = window.navigator;
let locale;
for (let i = 0; i < languages.length && !locale; i++) {
locale = isLocaleAvailable(languages[i], isSupportedByLibrary);
}
return locale || 'en';
} }
/* Check whether the locale or sub locale (e.g. en-US, en) is supported. /**
* Check whether the locale or sub locale (e.g. en-US, en) is supported.
* @private
* @param { String } locale - The locale to check for * @param { String } locale - The locale to check for
* @param { Function } available - Returns a boolean indicating whether the locale is supported * @param { Function } available - Returns a boolean indicating whether the locale is supported
*/ */
@ -59,49 +54,60 @@ function isLocaleAvailable (locale, available) {
if (available(locale)) { if (available(locale)) {
return locale; return locale;
} else { } else {
var sublocale = locale.split("-")[0]; var sublocale = locale.split('-')[0];
if (sublocale !== locale && available(sublocale)) { if (sublocale !== locale && available(sublocale)) {
return sublocale; return sublocale;
} }
} }
} }
/**
* Given a locale, return the closest locale returned by dayJS
* @private
* @param { string } locale
*/
function getDayJSLocale (locale) { function getDayJSLocale (locale) {
const dayjs_locale = locale.toLowerCase().replace('_', '-'); const dayjs_locale = locale.toLowerCase().replace('_', '-');
return dayjs_locale === 'ug' ? 'ug-cn' : dayjs_locale; return dayjs_locale === 'ug' ? 'ug-cn' : dayjs_locale;
} }
/**
/* Fetch the translations for the given local at the given URL. * Fetch the translations for the given local at the given URL.
* @private * @private
* @method i18n#fetchTranslations * @returns { Jed }
* @param { _converse }
*/ */
async function fetchTranslations (_converse) { async function fetchTranslations () {
const { api, locale } = _converse; const { api, locale } = _converse;
const dayjs_locale = getDayJSLocale(locale); const dayjs_locale = getDayJSLocale(locale);
if (!isConverseLocale(locale, api.settings.get("locales")) || locale === 'en') { if (!isConverseLocale(locale, api.settings.get('locales')) || locale === 'en') {
return; return;
} }
const { default: data } = await import(/*webpackChunkName: "locales/[request]" */ `../i18n/${locale}/LC_MESSAGES/converse.po`); const { default: data } = await import(
/*webpackChunkName: "locales/[request]" */ `../i18n/${locale}/LC_MESSAGES/converse.po`
);
await import(/*webpackChunkName: "locales/dayjs/[request]" */ `dayjs/locale/${dayjs_locale}.js`); await import(/*webpackChunkName: "locales/dayjs/[request]" */ `dayjs/locale/${dayjs_locale}.js`);
dayjs.locale(getLocale(dayjs_locale, l => dayjs.locale(l))); dayjs.locale(getLocale(dayjs_locale, (l) => dayjs.locale(l)));
jed_instance = new Jed(data); return new Jed(data);
} }
let jed_instance;
/** /**
* @namespace i18n * @namespace i18n
*/ */
Object.assign(i18n, { Object.assign(i18n, {
/**
* @param { string } preferred_locale
* @param { string[] } available_locales
*/
getLocale (preferred_locale, available_locales) { getLocale (preferred_locale, available_locales) {
return getLocale(preferred_locale, preferred => isConverseLocale(preferred, available_locales)); return getLocale(preferred_locale, (preferred) => isConverseLocale(preferred, available_locales));
}, },
/**
* @param { string } str - The string to be translated
*/
translate (str) { translate (str) {
if (!jed_instance) { if (!jed_instance) {
return Jed.sprintf.apply(Jed, arguments); return Jed.sprintf.apply(Jed, arguments);
@ -120,8 +126,8 @@ Object.assign(i18n, {
} else { } else {
try { try {
const preferred_locale = api.settings.get('i18n'); const preferred_locale = api.settings.get('i18n');
_converse.locale = i18n.getLocale(preferred_locale, api.settings.get("locales")); _converse.locale = i18n.getLocale(preferred_locale, api.settings.get('locales'));
await fetchTranslations(_converse); jed_instance = await fetchTranslations();
} catch (e) { } catch (e) {
log.fatal(e.message); log.fatal(e.message);
_converse.locale = 'en'; _converse.locale = 'en';
@ -131,7 +137,7 @@ Object.assign(i18n, {
__ (...args) { __ (...args) {
return i18n.translate(...args); return i18n.translate(...args);
} },
}); });
export const __ = i18n.__; export const __ = i18n.__;

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Converse.js 4.2.0\n" "Project-Id-Version: Converse.js 4.2.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-06-23 10:10+0200\n" "POT-Creation-Date: 2023-06-23 10:10+0200\n"
"PO-Revision-Date: 2022-12-15 06:49+0000\n" "PO-Revision-Date: 2023-06-29 05:51+0000\n"
"Last-Translator: ssantos <ssantos@web.de>\n" "Last-Translator: ssantos <ssantos@web.de>\n"
"Language-Team: Portuguese <https://hosted.weblate.org/projects/conversejs/" "Language-Team: Portuguese <https://hosted.weblate.org/projects/conversejs/"
"translations/pt/>\n" "translations/pt/>\n"
@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n" "Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.15-dev\n" "X-Generator: Weblate 4.18.1\n"
#: dist/converse-no-dependencies.js:29951 #: dist/converse-no-dependencies.js:29951
msgid "The connection has dropped, attempting to reconnect." msgid "The connection has dropped, attempting to reconnect."
@ -597,14 +597,12 @@ msgstr ""
"recarregar a página para solicitá-los novamente." "recarregar a página para solicitá-los novamente."
#: dist/converse-no-dependencies.js:58367 #: dist/converse-no-dependencies.js:58367
#, fuzzy
msgid "An error occurred while trying to fetch the command form" msgid "An error occurred while trying to fetch the command form"
msgstr "" msgstr "Ocorreu um erro ao tentar enviar o formulário de configuração"
"Desculpe, ocorreu um erro ao tentar enviar o formulário de configuração."
#: dist/converse-no-dependencies.js:58409 #: dist/converse-no-dependencies.js:58409
msgid "A timeout occurred" msgid "A timeout occurred"
msgstr "" msgstr "O tempo de espera se esgotou"
#: dist/converse-no-dependencies.js:60849 #: dist/converse-no-dependencies.js:60849
msgid "Timeout while trying to fetch archived messages." msgid "Timeout while trying to fetch archived messages."
@ -676,20 +674,19 @@ msgstr "Executar"
#: dist/converse-no-dependencies.js:74179 #: dist/converse-no-dependencies.js:74179
msgid "Previous" msgid "Previous"
msgstr "" msgstr "Anterior"
#: dist/converse-no-dependencies.js:74180 #: dist/converse-no-dependencies.js:74180
msgid "Next" msgid "Next"
msgstr "" msgstr "Próximo"
#: dist/converse-no-dependencies.js:74181 #: dist/converse-no-dependencies.js:74181
msgid "Complete" msgid "Complete"
msgstr "" msgstr "Completo"
#: dist/converse-no-dependencies.js:76835 #: dist/converse-no-dependencies.js:76835
#, fuzzy
msgid "Add to Contacts" msgid "Add to Contacts"
msgstr "Adicionar um contato" msgstr "Adicionar aos Contatos"
#: dist/converse-no-dependencies.js:76845 #: dist/converse-no-dependencies.js:76845
#: dist/converse-no-dependencies.js:90215 #: dist/converse-no-dependencies.js:90215
@ -943,27 +940,25 @@ msgstr ""
"programador para obter mais detalhes" "programador para obter mais detalhes"
#: dist/converse-no-dependencies.js:79561 #: dist/converse-no-dependencies.js:79561
#, fuzzy
msgid "Executing" msgid "Executing"
msgstr "Executar" msgstr "A executar"
#: dist/converse-no-dependencies.js:79568 #: dist/converse-no-dependencies.js:79568
#: dist/converse-no-dependencies.js:79573 #: dist/converse-no-dependencies.js:79573
msgid "Completed" msgid "Completed"
msgstr "" msgstr "Completo"
#: dist/converse-no-dependencies.js:79614 #: dist/converse-no-dependencies.js:79614
#, fuzzy
msgid "" msgid ""
"An error occurred while trying to cancel the command. See the developer " "An error occurred while trying to cancel the command. See the developer "
"console for details" "console for details"
msgstr "" msgstr ""
"Desculpe, ocorreu um erro ao tentar executar o comando. Veja o console do " "Ocorreu um erro ao tentar cancelar o comando. Veja o console do programador "
"programador para obter mais detalhes" "para obter mais detalhes"
#: dist/converse-no-dependencies.js:79621 #: dist/converse-no-dependencies.js:79621
msgid "Error: unexpected result" msgid "Error: unexpected result"
msgstr "" msgstr "Erro: resultado inesperado"
#: dist/converse-no-dependencies.js:80123 #: dist/converse-no-dependencies.js:80123
msgid "Bookmark this groupchat" msgid "Bookmark this groupchat"
@ -1003,9 +998,9 @@ msgid "Bookmarks"
msgstr "Favoritos" msgstr "Favoritos"
#: dist/converse-no-dependencies.js:80983 #: dist/converse-no-dependencies.js:80983
#, fuzzy, javascript-format #, javascript-format
msgid "Bookmark for \"%1$s\"" msgid "Bookmark for \"%1$s\""
msgstr "Favoritos" msgstr "Favorito para \"%1$s\""
#: dist/converse-no-dependencies.js:80984 #: dist/converse-no-dependencies.js:80984
msgid "Would you like this groupchat to be automatically joined upon startup?" msgid "Would you like this groupchat to be automatically joined upon startup?"
@ -1112,14 +1107,12 @@ msgid "Image: "
msgstr "Imagem: " msgstr "Imagem: "
#: dist/converse-no-dependencies.js:89948 #: dist/converse-no-dependencies.js:89948
#, fuzzy
msgid "Older versions" msgid "Older versions"
msgstr "Versões da mensagem" msgstr "Versões antigas"
#: dist/converse-no-dependencies.js:89950 #: dist/converse-no-dependencies.js:89950
#, fuzzy
msgid "No older versions found" msgid "No older versions found"
msgstr "Servidor remoto não encontrado" msgstr "Nenhuma versão anterior encontrada"
#: dist/converse-no-dependencies.js:89950 #: dist/converse-no-dependencies.js:89950
msgid "Current version" msgid "Current version"
@ -1499,9 +1492,8 @@ msgstr "Visitante"
#. harmony default export #. harmony default export
#: dist/converse-no-dependencies.js:107043 #: dist/converse-no-dependencies.js:107043
#, fuzzy
msgid "Participant" msgid "Participant"
msgstr "Participantes" msgstr "Participante"
#: dist/converse-no-dependencies.js:107043 #: dist/converse-no-dependencies.js:107043
msgid "Participants" msgid "Participants"
@ -1814,9 +1806,8 @@ msgid "Configure this groupchat"
msgstr "Configurar essa sala" msgstr "Configurar essa sala"
#: dist/converse-no-dependencies.js:111026 #: dist/converse-no-dependencies.js:111026
#, fuzzy
msgid "Change the nickname you're using in this groupchat" msgid "Change the nickname you're using in this groupchat"
msgstr "Registre um nome para esse bate-papo" msgstr "Alterar o apelido que usa neste bate-papo"
#: dist/converse-no-dependencies.js:111039 #: dist/converse-no-dependencies.js:111039
msgid "Invite someone to join this groupchat" msgid "Invite someone to join this groupchat"
@ -1988,61 +1979,56 @@ msgid "Profile"
msgstr "Perfil" msgstr "Perfil"
#: dist/converse-no-dependencies.js:114853 #: dist/converse-no-dependencies.js:114853
#, fuzzy
msgid "Reset Password" msgid "Reset Password"
msgstr "Palavra-passe" msgstr "Resetar palavra-passe"
#: dist/converse-no-dependencies.js:114891 #: dist/converse-no-dependencies.js:114891
msgid "The new passwords must match" msgid "The new passwords must match"
msgstr "" msgstr "As novas palavras-passe devem corresponder"
#: dist/converse-no-dependencies.js:114892 #: dist/converse-no-dependencies.js:114892
#, fuzzy
msgid "New password" msgid "New password"
msgstr "Sem palavra-passe" msgstr "Nova palavra-passe"
#: dist/converse-no-dependencies.js:114893 #: dist/converse-no-dependencies.js:114893
#, fuzzy
msgid "Confirm new password" msgid "Confirm new password"
msgstr "Sem palavra-passe" msgstr "Confirme a nova palavra-passe"
#: dist/converse-no-dependencies.js:115415 #: dist/converse-no-dependencies.js:115415
#, fuzzy
msgid "Timeout error" msgid "Timeout error"
msgstr "Erro de Expiração" msgstr "Erro de tempo de espera"
#: dist/converse-no-dependencies.js:115422 #: dist/converse-no-dependencies.js:115422
msgid "Your server does not support in-band password reset" msgid "Your server does not support in-band password reset"
msgstr "" msgstr "O seu servidor não suporta a redefinição de palavra-passe aqui"
#: dist/converse-no-dependencies.js:115429 #: dist/converse-no-dependencies.js:115429
msgid "" msgid ""
"Your server responded with an unknown error, check the console for details" "Your server responded with an unknown error, check the console for details"
msgstr "" msgstr ""
"O seu servidor respondeu com um erro desconhecido, verifique o console de "
"programador para detalhes"
#: dist/converse-no-dependencies.js:115448 #: dist/converse-no-dependencies.js:115448
#, fuzzy
msgid "Timeout error while trying to set your password" msgid "Timeout error while trying to set your password"
msgstr "O tempo esgotou ao tentar definir a afiliação" msgstr "O tempo esgotou ao tentar definir a sua palavra-passe"
#: dist/converse-no-dependencies.js:115450 #: dist/converse-no-dependencies.js:115450
msgid "Your server does not allow in-band password reset" msgid "Your server does not allow in-band password reset"
msgstr "" msgstr "O seu servidor não suporta a redefinição de palavra-passe aqui"
#: dist/converse-no-dependencies.js:115452 #: dist/converse-no-dependencies.js:115452
#: dist/converse-no-dependencies.js:115454 #: dist/converse-no-dependencies.js:115454
#, fuzzy
msgid "You are not allowed to change your password" msgid "You are not allowed to change your password"
msgstr "Não está autorizado a criar novas salas de conversação." msgstr "Não tem permissão para alterar a sua palavra-passe"
#: dist/converse-no-dependencies.js:115456 #: dist/converse-no-dependencies.js:115456
msgid "Success" msgid "Success"
msgstr "" msgstr "Sucesso"
#: dist/converse-no-dependencies.js:115456 #: dist/converse-no-dependencies.js:115456
#, fuzzy
msgid "Your new password has been set" msgid "Your new password has been set"
msgstr "Foi criada uma nova sala de conversação" msgstr "A sua palavra-passe nova foi definida"
#. eslint-disable-line class-methods-use-this #. eslint-disable-line class-methods-use-this
#: dist/converse-no-dependencies.js:116001 #: dist/converse-no-dependencies.js:116001
@ -2498,9 +2484,8 @@ msgid "Add a new groupchat"
msgstr "Adicionar uma nova sala" msgstr "Adicionar uma nova sala"
#: dist/converse-no-dependencies.js:126601 #: dist/converse-no-dependencies.js:126601
#, fuzzy
msgid "Show bookmarked groupchats" msgid "Show bookmarked groupchats"
msgstr "Mostrar Salas" msgstr "Mostrar bate-papos favoritos"
#: dist/converse-no-dependencies.js:127178 #: dist/converse-no-dependencies.js:127178
#, javascript-format #, javascript-format
@ -2513,9 +2498,8 @@ msgid "Add"
msgstr "Adicionar" msgstr "Adicionar"
#: dist/converse-no-dependencies.js:127683 #: dist/converse-no-dependencies.js:127683
#, fuzzy
msgid "Group" msgid "Group"
msgstr "Grupos" msgstr "Grupo"
#. eslint-disable-line class-methods-use-this #. eslint-disable-line class-methods-use-this
#: dist/converse-no-dependencies.js:127892 #: dist/converse-no-dependencies.js:127892
@ -2538,12 +2522,11 @@ msgstr "Clique para ocultar estes contactos"
#. harmony default export #. harmony default export
#: dist/converse-no-dependencies.js:128134 #: dist/converse-no-dependencies.js:128134
msgid "Contacts" msgid "Contacts"
msgstr "Contatos" msgstr "Contactos"
#: dist/converse-no-dependencies.js:128135 #: dist/converse-no-dependencies.js:128135
#, fuzzy
msgid "Click to toggle contacts" msgid "Click to toggle contacts"
msgstr "Clique para ocultar estes contactos" msgstr "Clique para mostrar/esconder os contatos"
#: dist/converse-no-dependencies.js:128136 #: dist/converse-no-dependencies.js:128136
msgid "Add a contact" msgid "Add a contact"

View File

@ -4,7 +4,7 @@ import log from "@converse/headless/log";
import sizzle from 'sizzle'; import sizzle from 'sizzle';
import tplAlertComponent from "./templates/modal-alert.js"; import tplAlertComponent from "./templates/modal-alert.js";
import { View } from '@converse/skeletor/src/view.js'; import { View } from '@converse/skeletor/src/view.js';
import { addClass, removeElement } from '../../utils/html.js'; import { hasClass, addClass, removeElement, removeClass } from '../../utils/html.js';
import { render } from 'lit'; import { render } from 'lit';
import './styles/_modal.scss'; import './styles/_modal.scss';
@ -43,7 +43,7 @@ const BaseModal = View.extend({
}, },
onHide () { onHide () {
u.removeClass('selected', this.trigger_el); removeClass('selected', this.trigger_el);
!this.persistent && api.modal.remove(this); !this.persistent && api.modal.remove(this);
}, },

View File

@ -10,16 +10,14 @@ export class ConverseBrandByline extends CustomElement {
return html` return html`
${is_fullscreen ${is_fullscreen
? html` ? html`
<p class="brand-subtitle">${_converse.VERSION_NAME}</p>
<p class="brand-subtitle"> <p class="brand-subtitle">
<a target="_blank" rel="nofollow" href="https://conversejs.org">Open Source</a> XMPP chat client Une messagerie instantanée qui respecte vos libertés et votre vie privée.
brought to you by <a target="_blank" rel="nofollow" href="https://opkode.com">Opkode</a>
</p> </p>
<p class="brand-subtitle"> <p class="brand-subtitle">
<a target="_blank" rel="nofollow" href="https://hosted.weblate.org/projects/conversejs/#languages" Application Web qui s'appuie sur <a target="_blank" rel="nofollow" href="https://conversejs.org">ConverseJS</a>,
>Translate</a un client XMPP conçu par <a target="_blank" rel="nofollow" href="https://opkode.com">Opkode</a>
> <br/>
it into your own language <small>${_converse.VERSION_NAME}</small>
</p> </p>
` `
: ''} : ''}

View File

@ -8,38 +8,55 @@ export class ConverseBrandLogo extends CustomElement {
render () { // eslint-disable-line class-methods-use-this render () { // eslint-disable-line class-methods-use-this
const is_fullscreen = api.settings.get('view_mode') === 'fullscreen'; const is_fullscreen = api.settings.get('view_mode') === 'fullscreen';
return html` return html`
<a class="brand-heading" href="https://conversejs.org" target="_blank" rel="noopener"> <a class="brand-heading" href="https://chapril.org/XMPP" target="_blank" rel="noopener">
<span class="brand-name-wrapper ${is_fullscreen ? 'brand-name-wrapper--fullscreen' : ''}"> <span class="brand-name-wrapper ${is_fullscreen ? 'brand-name-wrapper--fullscreen' : ''}">
<svg
class="converse-svg-logo"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 364 364">
<title>Converse</title> <svg
<g class="cls-1" id="g904"> xmlns:dc="http://purl.org/dc/elements/1.1/"
<g data-name="Layer 2"> xmlns:cc="http://creativecommons.org/ns#"
<g data-name="Layer 7"> xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
<path xmlns:svg="http://www.w3.org/2000/svg"
class="cls-3" xmlns="http://www.w3.org/2000/svg"
d="M221.46,103.71c0,18.83-29.36,18.83-29.12,0C192.1,84.88,221.46,84.88,221.46,103.71Z" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
/> xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
<path id="chapril-logo"
class="cls-4" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"
d="M179.9,4.15A175.48,175.48,0,1,0,355.38,179.63,175.48,175.48,0,0,0,179.9,4.15Zm-40.79,264.5c-.23-17.82,27.58-17.82,27.58,0S138.88,286.48,139.11,268.65ZM218.6,168.24A79.65,79.65,0,0,1,205.15,174a12.76,12.76,0,0,0-6.29,4.65L167.54,222a1.36,1.36,0,0,1-2.46-.8v-35.8a2.58,2.58,0,0,0-3.06-2.53c-15.43,3-30.23,7.7-42.73,19.94-38.8,38-29.42,105.69,16.09,133.16a162.25,162.25,0,0,1-91.47-67.27C-3.86,182.26,34.5,47.25,138.37,25.66c46.89-9.75,118.25,5.16,123.73,62.83C265.15,120.64,246.56,152.89,218.6,168.24Z" class="converse-svg-logo"
/> xml:space="preserve" version="1.1"
</g> viewBox="0 0 376 311" height="20%" width="6rem"
</g> sodipodi:docname="chapril-logo.svg" inkscape:version="0.92.1 r15371">
</g> <sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="640" inkscape:window-height="480" id="namedview16" showgrid="false" inkscape:zoom="0.75884244" inkscape:cx="188" inkscape:cy="155.5" inkscape:window-x="0" inkscape:window-y="24" inkscape:window-maximized="0" inkscape:current-layer="svg108"/>
</svg> <metadata id="metadata114">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
<cc:license rdf:resource="GFDL version 1.3 ou ultérieure, Creative Commons By Sa version 2.0 ou ultérieure, Licence Art Libre version 1.3 ou ultérieure"/>
<dc:creator>
<cc:Agent>
<dc:title>Antoine BARDELLI</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
</rdf:RDF>
</metadata>
<defs id="defs112"/>
<g id="g250" style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" transform="translate(4.6079614e-7,-4.4571451e-6)">
<path id="path124" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 96.70711,209.69029 c -2.742,1.114 -5.399,1.8 -7.885,2.057 -0.771,0.085 -1.629,0.171 -2.4,0.171 -2.571,0 -5.314,-0.428 -8.228,-1.286 -2.486,-0.857 -4.628,-2.314 -6.514,-4.371 -1.886,-1.8 -3.343,-3.942 -4.371,-6.428 -0.943,-2.486 -1.457,-5.057 -1.543,-7.714 0,-0.086 0,-0.257 0,-0.343 0,-2.485 0.514,-4.971 1.543,-7.371 1.028,-2.314 2.485,-4.457 4.371,-6.428 1.886,-2.057 4.028,-3.514 6.514,-4.371 2.828,-1.029 5.571,-1.543 8.142,-1.543 0.257,0 0.6,0 0.857,0 3.686,0.171 6.857,1.028 9.686,2.657 -0.086,1.457 -0.343,3.514 -0.6,6.343 -2.743,-1.372 -5.4,-2.143 -7.971,-2.315 -1.972,-0.171 -3.943,0.086 -6,0.772 -1.629,0.514 -3.171,1.457 -4.457,2.914 -1.286,1.371 -2.228,2.828 -2.914,4.457 -0.772,1.628 -1.114,3.342 -1.114,5.142 0.085,1.886 0.428,3.6 1.114,5.229 0.686,1.714 1.628,3.171 2.914,4.457 1.286,1.285 2.828,2.228 4.457,2.914 2.486,0.685 4.543,1.028 6.343,1.028 3.342,-0.343 5.999,-1.2 8.056,-2.657 0,1.457 0,3.686 0,6.686 z"/>
<path id="path126" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 137.33411,184.91929 c 0,1.8 0,3.515 0,5.314 0,2.657 0,5.4 -0.086,8.057 0,4.457 0,8.743 0,12.771 -1.714,0 -4.285,0 -7.799,0 0,-3.857 0,-11.571 0.085,-23.142 0.086,-1.114 -0.171,-2.228 -0.6,-3.257 -0.428,-1.028 -1.028,-1.971 -1.8,-2.742 -0.942,-0.943 -2.142,-1.715 -3.599,-2.143 -1.029,-0.257 -2.229,-0.429 -3.6,-0.343 -1.115,0.086 -2.229,0.343 -3.257,0.686 -1.029,0.428 -2.143,1.028 -3.343,1.8 -0.6,0.6 -1.029,1.2 -1.457,1.8 v 27.341 h -8.057 v -62.997 h 8.057 v 29.313 c 0.943,-1.114 1.8,-1.971 2.571,-2.486 1.629,-0.942 3,-1.542 4.2,-1.885 1.971,-0.429 3.771,-0.6 5.571,-0.6 2.143,0.085 3.943,0.343 5.4,0.943 1.543,0.6 2.914,1.542 4.028,2.742 2.4,2.572 3.6,5.486 3.686,8.828 z"/>
<path id="path128" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 169.38911,146.86429 c 4.714,10.714 14.228,32.056 28.37,64.111 -1.371,0 -4.114,0 -8.313,0 -1.286,-2.657 -3.772,-7.971 -7.543,-15.942 -4.028,0 -12.085,0 -24.17,0 -1.114,2.657 -3.514,7.971 -7.028,15.942 -1.457,0 -4.2,0 -8.4,0 4.543,-10.713 13.542,-32.055 27.084,-64.111 z m 9.171,40.884 c -1.457,-3.686 -4.542,-10.885 -9.085,-21.77 -1.457,3.599 -4.285,10.885 -8.571,21.77 3,0 8.828,0 17.656,0 z"/>
<path id="path130" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 212.15911,199.83329 c 0.257,0.429 0.6,0.771 0.857,1.114 1.114,1.457 2.657,2.743 4.457,3.686 1.457,0.685 3.085,1.028 4.8,1.028 0.085,0 0.257,0 0.428,0 1.8,0.086 3.514,-0.257 5.143,-1.028 1.628,-0.6 3.171,-1.629 4.457,-2.914 1.285,-1.286 2.228,-2.743 2.914,-4.457 0.685,-1.543 1.028,-3.343 1.028,-5.314 0.086,-1.715 -0.257,-3.429 -1.028,-5.057 -0.6,-1.629 -1.629,-3.171 -2.914,-4.457 -1.286,-1.286 -2.743,-2.229 -4.457,-2.914 -1.115,-0.515 -2.572,-0.772 -4.2,-0.772 -0.172,0 -0.343,0 -0.429,0 -2.657,0.086 -4.714,0.429 -5.999,1.2 -3.429,1.8 -5.143,3.857 -5.143,6.171 0,3 0,7.629 0.086,13.714 z m 0,8.314 c -0.086,3.343 -0.086,10.028 -0.086,20.056 -1.286,0 -4.028,0 -8.057,0 v -54.769 c 2.657,0 5.4,0 8.057,0 0.086,1.286 0.086,2.4 0.086,3.257 0.857,-1.114 2.314,-2.142 4.457,-3.085 2.4,-1.029 4.971,-1.543 7.714,-1.543 2.657,0 5.228,0.514 7.628,1.543 2.485,1.028 4.714,2.485 6.514,4.371 1.971,1.886 3.428,4.028 4.371,6.428 1.028,2.486 1.543,4.971 1.543,7.543 0,0.085 0,0.085 0,0.171 0,2.657 -0.515,5.228 -1.543,7.714 -1.029,2.486 -2.486,4.628 -4.371,6.428 -1.886,1.972 -4.029,3.429 -6.514,4.371 -2.486,1.029 -5.057,1.543 -7.628,1.543 -2.657,-0.085 -5.229,-0.6 -7.714,-1.543 -1.372,-0.514 -2.829,-1.371 -4.457,-2.485 z"/>
<path id="path132" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 271.04211,180.46329 c 0,-0.086 -0.686,-0.172 -2.143,-0.429 -2.743,-0.086 -5.228,0.857 -7.371,2.828 -0.857,0.772 -1.543,1.886 -2.057,3.343 -0.343,1.371 -0.515,2.829 -0.6,4.457 0,4.543 0,11.399 0,20.399 -1.286,0 -3.943,0 -7.971,0 0,-6.257 0,-18.856 -0.086,-37.627 1.286,0 3.943,0 7.8,0 0.085,0.772 0.085,2.4 0.085,4.8 0,0.514 0,1.543 -0.085,3.171 1.028,-4.199 3.085,-6.856 6.085,-7.971 1.2,-0.343 2.4,-0.514 3.686,-0.514 0.857,-0.086 1.714,0 2.657,0.171 0,1.629 0,4.115 0,7.372 z"/>
<path id="path134" style="clip-rule:evenodd;fill:#005184;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 277.47011,163.23529 c 0,-1.372 0.514,-2.4 1.457,-3.171 0.943,-0.772 1.971,-1.2 3.085,-1.2 0.086,0 0.172,0 0.258,0 1.114,0 2.057,0.342 2.999,1.028 0.943,0.771 1.372,1.8 1.372,3.257 0,1.457 -0.429,2.571 -1.372,3.428 -0.942,0.858 -2.057,1.286 -3.257,1.286 -1.114,0 -2.142,-0.428 -3.085,-1.2 -0.943,-0.771 -1.457,-1.971 -1.457,-3.428 z"/>
<path style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41420996" id="path136" d="m 278.15611,173.34929 c 1.371,0 4.028,0 8.056,0 0,6.342 0,18.942 0,37.883 -1.285,0 -3.942,0 -7.885,0 0,-6.256 -0.086,-18.941 -0.171,-37.883 z"/>
<path id="path138" style="clip-rule:evenodd;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 295.55511,146.26429 v 64.797 c 1.285,0 3.942,0 7.885,0 0,-10.799 0,-32.398 0,-64.797 -1.286,0 -3.943,0 -7.885,0 z"/>
<path id="path144" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 79.90511,45.008286 c 0.902,0.305 0.903,0.306 1.74,0.76 0,0 2.36,1.6 3.541,2.399 16.192,11.056 46.905,36.807 46.905,36.807 l -0.62,0.933 c 0,0 -30.962,-17.269 -47.812,-25.837 -0.154,2.104 -0.309,4.208 -0.465,6.312 l -0.126,1.689 c -0.635,7.993 -1.295,15.97 -2,23.945 l -0.096,1.076 c -0.824,8.583004 -1.124,17.369004 -3.069,25.573004 -1.802,7.601 -10.27,13.477 -15.485,20.114 -10.856,13.816 -19.361,29.582 -21.64,47.603 -2.579,20.389 5.773,40.853 21.062,55.815 5.92,5.794 12.534,10.853 19.323,15.617 l -3.768,5.852 c -20.581,-12.139 -40.182,-28.618 -47.181,-51.981 -6.615,-22.081 -1.608,-47.917 10.144,-67.278 6.689,-11.02 14.834,-21.098 23.413,-30.201 0,0 0.585,-2.521 0.874,-4.27 3.14,-19.016004 5.383,-38.057004 7.92,-57.227004 l 0.274,-2.074 0.28,-1.686 c 0.307,-0.8 0.337,-1.033 0.841,-1.737 1.119,-1.562 2.062,-2.818 5.945,-2.204 z"/>
<path id="path146" style="clip-rule:evenodd;fill:#005184;fill-rule:nonzero;stroke-linejoin:round;stroke-miterlimit:1.41420996" d="m 300.65411,44.858286 c 2.74,0.486 2.778,0.936 3.448,1.587 2.555,2.484 2.191,7.238 2.75,11.471 2.467,18.612 4.172,37.353 7.871,55.935004 0,0 3.607,4.013 6.264,7.099 11.064,12.849 21.019,26.411 26.284,43.975 6.27,20.92 3.585,41.82 -7.633,60.315 -9.349,15.414 -24.268,26.668 -39.964,35.962 l -0.593,-1.853 c 17.279,-12.08 34.133,-26.972 39.318,-48.24 3.677,-15.083 -0.809,-32.515 -6.571,-47.292 -5.094,-13.065 -14.589,-24.209 -23.233,-34.394 -1.789,-2.107 -3.603,-4.192 -5.472,-6.229 0,0 -2.204,-3.069 -2.806,-6.739 -2.582,-15.749 -3.416,-31.540004 -4.699,-47.326004 0,0 -0.34,-4.424 -0.589,-7.754 l -0.098,-1.322 -30.582,18.428 -15.221,9.11 -0.801,0.477 -3.955,-6.151 0.767,-0.531 14.605,-10.067 37.28,-25.534 c 0,0 1.172,-0.939 3.63,-0.927 z m 14.362,70.312004 c 0.178,0.639 -0.049,-0.186 0,0 z"/>
</g>
</svg>
<span class="brand-name"> <span class="brand-name">
<span class="brand-name__text">converse<span class="subdued">.js</span></span> <span class="brand-name__text">Tchat Chapril</span>
${is_fullscreen
? html`
<p class="byline">messaging freedom</p>
`
: ''}
</span> </span>
</span> </span>
</a> </a>

View File

@ -28,6 +28,7 @@ export default class ConverseGIFElement extends CustomElement {
constructor () { constructor () {
super(); super();
this.src = null;
this.autoplay = false; this.autoplay = false;
this.noloop = false; this.noloop = false;
this.fallback = 'url'; this.fallback = 'url';
@ -90,8 +91,6 @@ export default class ConverseGIFElement extends CustomElement {
onControlsClicked (ev) { onControlsClicked (ev) {
ev.preventDefault(); ev.preventDefault();
if (this.supergif.playing) { if (this.supergif.playing) {
this.supergif.pause(); this.supergif.pause();
} else if (this.supergif.frames.length > 0) { } else if (this.supergif.frames.length > 0) {

View File

@ -16,6 +16,14 @@ export default class Image extends CustomElement {
} }
} }
constructor () {
super();
this.src = null;
this.href = null;
this.onImgClick = null;
this.onImgLoad = null;
}
render () { render () {
if (isGIFURL(this.src) && shouldRenderMediaFromURL(this.src, 'image')) { if (isGIFURL(this.src) && shouldRenderMediaFromURL(this.src, 'image')) {
return tplGif(filterQueryParamsFromURL(this.src), true); return tplGif(filterQueryParamsFromURL(this.src), true);

View File

@ -1,22 +1,11 @@
/** import log from '@converse/headless/log.js';
* @copyright Shachaf Ben-Kiki, JC Brand
* @description
* Started as a fork of Shachaf Ben-Kiki's jsgif library
* https://github.com/shachaf/jsgif
* @license MIT License
*/
import Stream from './stream.js';
import { getOpenPromise } from '@converse/openpromise'; import { getOpenPromise } from '@converse/openpromise';
import { parseGIF } from './utils.js'; import { parseGIF, decompressFrames } from 'gifuct-js';
const DELAY_FACTOR = 10;
export default class ConverseGif { export default class ConverseGif {
/** /**
* Creates a new ConverseGif instance * Creates a new ConverseGif instance
* @param { HTMLElement } el * @param { import('lit').LitElement } el
* @param { Object } [options] * @param { Object } [options]
* @param { Number } [options.width] - The width, in pixels, of the canvas * @param { Number } [options.width] - The width, in pixels, of the canvas
* @param { Number } [options.height] - The height, in pixels, of the canvas * @param { Number } [options.height] - The height, in pixels, of the canvas
@ -30,7 +19,8 @@ export default class ConverseGif {
* @param { Number } [options.progress_bar_height=5] * @param { Number } [options.progress_bar_height=5]
*/ */
constructor (el, opts) { constructor (el, opts) {
this.options = Object.assign({ this.options = Object.assign(
{
width: null, width: null,
height: null, height: null,
autoplay: true, autoplay: true,
@ -38,7 +28,7 @@ export default class ConverseGif {
show_progress_bar: true, show_progress_bar: true,
progress_bg_color: 'rgba(0,0,0,0.4)', progress_bg_color: 'rgba(0,0,0,0.4)',
progress_color: 'rgba(255,0,22,.8)', progress_color: 'rgba(255,0,22,.8)',
progress_bar_height: 5 progress_bar_height: 5,
}, },
opts opts
); );
@ -47,25 +37,23 @@ export default class ConverseGif {
this.gif_el = el.querySelector('img'); this.gif_el = el.querySelector('img');
this.canvas = el.querySelector('canvas'); this.canvas = el.querySelector('canvas');
this.ctx = this.canvas.getContext('2d'); this.ctx = this.canvas.getContext('2d');
// It's good practice to pre-render to an offscreen canvas
// Offscreen canvas with full gif
this.offscreenCanvas = document.createElement('canvas'); this.offscreenCanvas = document.createElement('canvas');
// Offscreen canvas for patches
this.patchCanvas = document.createElement('canvas');
this.ctx_scaled = false; this.ctx_scaled = false;
this.disposal_method = null;
this.disposal_restore_from_idx = null;
this.frame = null;
this.frame_offsets = []; // elements have .x and .y properties
this.frames = []; this.frames = [];
this.last_disposal_method = null;
this.last_img = null;
this.load_error = null; this.load_error = null;
this.playing = this.options.autoplay; this.playing = this.options.autoplay;
this.transparency = null;
this.frame_delay = null;
this.frame_idx = 0; this.frame_idx = 0;
this.iteration_count = 0; this.iteration_count = 0;
this.start = null; this.start = null;
this.hovering = null;
this.frameImageData = null;
this.disposal_restore_from_idx = null;
this.initialize(); this.initialize();
} }
@ -75,7 +63,7 @@ export default class ConverseGif {
this.setSizes(this.options.width, this.options.height); this.setSizes(this.options.width, this.options.height);
} }
const data = await this.fetchGIF(this.gif_el.src); const data = await this.fetchGIF(this.gif_el.src);
requestAnimationFrame(() => this.startParsing(data)); requestAnimationFrame(() => this.handleGIFResponse(data));
} }
initPlayer () { initPlayer () {
@ -87,10 +75,10 @@ export default class ConverseGif {
// Show the first frame // Show the first frame
this.frame_idx = 0; this.frame_idx = 0;
this.putFrame(this.frame_idx); this.renderImage();
if (this.options.autoplay) { if (this.options.autoplay) {
const delay = (this.frames[this.frame_idx]?.delay ?? 0) * DELAY_FACTOR; const delay = this.frames[this.frame_idx]?.delay ?? 0;
setTimeout(() => this.play(), delay); setTimeout(() => this.play(), delay);
} }
} }
@ -127,18 +115,18 @@ export default class ConverseGif {
* `frame_delay` parameters can also be passed in. The `timestamp` * `frame_delay` parameters can also be passed in. The `timestamp`
* parameter comes from `requestAnimationFrame`. * parameter comes from `requestAnimationFrame`.
* *
* The purpose of this method is to call `putFrame` with the right delay * The purpose of this method is to call `renderImage` with the right delay
* in order to render the GIF animation. * in order to render the GIF animation.
* *
* Note, this method will cause the *next* upcoming frame to be rendered, * Note, this method will cause the *next* upcoming frame to be rendered,
* not the current one. * not the current one.
* *
* This means `this.frame_idx` will be incremented before calling `this.putFrame`, so * This means `this.frame_idx` will be incremented before calling `this.renderImage`, so
* `putFrame(0)` needs to be called *before* this method, otherwise the * `renderImage(0)` needs to be called *before* this method, otherwise the
* animation will incorrectly start from frame #1 (this is done in `initPlayer`). * animation will incorrectly start from frame #1 (this is done in `initPlayer`).
* *
* @param { DOMHighRestTimestamp } timestamp - The timestamp as returned by `requestAnimationFrame` * @param { DOMHighResTimeStamp } timestamp - The timestamp as returned by `requestAnimationFrame`
* @param { DOMHighRestTimestamp } previous_timestamp - The timestamp from the previous iteration of this method. * @param { DOMHighResTimeStamp } previous_timestamp - The timestamp from the previous iteration of this method.
* We need this in order to calculate whether we have waited long enough to * We need this in order to calculate whether we have waited long enough to
* show the next frame. * show the next frame.
* @param { Number } frame_delay - The delay (in 1/100th of a second) * @param { Number } frame_delay - The delay (in 1/100th of a second)
@ -148,10 +136,10 @@ export default class ConverseGif {
if (!this.playing) { if (!this.playing) {
return; return;
} }
if ((timestamp - previous_timestamp) < frame_delay) { if (timestamp - previous_timestamp < frame_delay) {
this.hovering ? this.drawPauseIcon() : this.putFrame(this.frame_idx); this.hovering ? this.drawPauseIcon() : this.renderImage();
// We need to wait longer // We need to wait longer
requestAnimationFrame(ts => this.onAnimationFrame(ts, previous_timestamp, frame_delay)); requestAnimationFrame((ts) => this.onAnimationFrame(ts, previous_timestamp, frame_delay));
return; return;
} }
const next_frame = this.getNextFrameNo(); const next_frame = this.getNextFrameNo();
@ -159,9 +147,9 @@ export default class ConverseGif {
return; return;
} }
this.frame_idx = next_frame; this.frame_idx = next_frame;
this.putFrame(this.frame_idx); this.renderImage();
const delay = (this.frames[this.frame_idx]?.delay || 8) * DELAY_FACTOR; const delay = this.frames[this.frame_idx]?.delay || 8;
requestAnimationFrame(ts => this.onAnimationFrame(ts, timestamp, delay)); requestAnimationFrame((ts) => this.onAnimationFrame(ts, timestamp, delay));
} }
setSizes (w, h) { setSizes (w, h) {
@ -175,19 +163,6 @@ export default class ConverseGif {
this.offscreenCanvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0); this.offscreenCanvas.getContext('2d').setTransform(1, 0, 0, 1, 0, 0);
} }
setFrameOffset (frame, offset) {
if (!this.frame_offsets[frame]) {
this.frame_offsets[frame] = offset;
return;
}
if (typeof offset.x !== 'undefined') {
this.frame_offsets[frame].x = offset.x;
}
if (typeof offset.y !== 'undefined') {
this.frame_offsets[frame].y = offset.y;
}
}
doShowProgress (pos, length, draw) { doShowProgress (pos, length, draw) {
if (draw && this.options.show_progress_bar) { if (draw && this.options.show_progress_bar) {
let height = this.options.progress_bar_height; let height = this.options.progress_bar_height;
@ -207,56 +182,36 @@ export default class ConverseGif {
/** /**
* Starts parsing the GIF stream data by calling `parseGIF` and passing in * Starts parsing the GIF stream data by calling `parseGIF` and passing in
* a map of handler functions. * a map of handler functions.
* @param { String } data - The GIF file data, as returned by the server * @param {ArrayBuffer} data - The GIF file data, as returned by the server
*/ */
startParsing (data) { handleGIFResponse (data) {
const stream = new Stream(data);
/**
* @typedef { Object } GIFParserHandlers
* A map of callback functions passed `parseGIF`. These functions are
* called as various parts of the GIF file format are parsed.
* @property { Function } hdr - Callback to handle the GIF header data
* @property { Function } gce - Callback to handle the GIF Graphic Control Extension data
* @property { Function } com - Callback to handle the comment extension block
* @property { Function } img - Callback to handle image data
* @property { Function } eof - Callback once the end of file has been reached
*/
const handler = {
'hdr': this.withProgress(stream, header => this.handleHeader(header)),
'gce': this.withProgress(stream, gce => this.handleGCE(gce)),
'com': this.withProgress(stream, ),
'img': this.withProgress(stream, img => this.doImg(img), true),
'eof': () => this.handleEOF(stream)
};
try { try {
parseGIF(stream, handler); const gif = parseGIF(data);
this.hdr = gif.header;
this.lsd = gif.lsd;
this.setSizes(this.options.width ?? this.lsd.width, this.options.height ?? this.lsd.height);
this.frames = decompressFrames(gif, true);
} catch (err) { } catch (err) {
this.showError('parse'); this.showError();
} }
this.initPlayer();
!this.options.autoplay && this.drawPlayIcon();
} }
drawError () { drawError () {
this.ctx.fillStyle = 'black'; this.ctx.fillStyle = 'black';
this.ctx.fillRect( this.ctx.fillRect(0, 0, this.options.width, this.options.height);
0,
0,
this.options.width ? this.options.width : this.hdr.width,
this.options.height ? this.options.height : this.hdr.height
);
this.ctx.strokeStyle = 'red'; this.ctx.strokeStyle = 'red';
this.ctx.lineWidth = 3; this.ctx.lineWidth = 3;
this.ctx.moveTo(0, 0); this.ctx.moveTo(0, 0);
this.ctx.lineTo( this.ctx.lineTo(this.options.width, this.options.height);
this.options.width ? this.options.width : this.hdr.width, this.ctx.moveTo(0, this.options.height);
this.options.height ? this.options.height : this.hdr.height this.ctx.lineTo(this.options.width, 0);
);
this.ctx.moveTo(0, this.options.height ? this.options.height : this.hdr.height);
this.ctx.lineTo(this.options.width ? this.options.width : this.hdr.width, 0);
this.ctx.stroke(); this.ctx.stroke();
} }
showError (errtype) { showError () {
this.load_error = errtype; this.load_error = true;
this.hdr = { this.hdr = {
width: this.gif_el.width, width: this.gif_el.width,
height: this.gif_el.height, height: this.gif_el.height,
@ -266,51 +221,11 @@ export default class ConverseGif {
this.el.requestUpdate(); this.el.requestUpdate();
} }
handleHeader (header) { manageDisposal (i) {
this.hdr = header; if (i <= 0) return;
this.setSizes(
this.options.width ?? this.hdr.width,
this.options.height ?? this.hdr.height
);
}
/**
* Handler for GIF Graphic Control Extension (GCE) data
*/
handleGCE (gce) {
this.pushFrame();
this.clear();
this.frame_delay = gce.delayTime;
this.transparency = gce.transparencyGiven ? gce.transparencyIndex : null;
this.disposal_method = gce.disposalMethod;
}
/**
* Handler for when the end of the GIF's file has been reached
*/
handleEOF (stream) {
this.pushFrame();
this.doDecodeProgress(stream, false);
this.initPlayer();
!this.options.autoplay && this.drawPlayIcon();
}
pushFrame () {
if (!this.frame) return;
this.frames.push({
data: this.frame.getImageData(0, 0, this.hdr.width, this.hdr.height),
delay: this.frame_delay
});
this.frame_offsets.push({ x: 0, y: 0 });
}
doImg (img) {
this.frame = this.frame || this.offscreenCanvas.getContext('2d');
const currIdx = this.frames.length;
//ct = color table, gct = global color table
const ct = img.lctFlag ? img.lct : this.hdr.gct; // TODO: What if neither exists?
const offscreenContext = this.offscreenCanvas.getContext('2d');
const disposal = this.frames[i - 1].disposalType;
/* /*
* Disposal method indicates the way in which the graphic is to * Disposal method indicates the way in which the graphic is to
* be treated after being displayed. * be treated after being displayed.
@ -328,94 +243,75 @@ export default class ConverseGif {
* Importantly, "previous" means the frame state * Importantly, "previous" means the frame state
* after the last disposal of method 0, 1, or 2. * after the last disposal of method 0, 1, or 2.
*/ */
if (currIdx > 0) { if (i > 1) {
if (this.last_disposal_method === 3) { if (disposal === 3) {
// Restore to previous // eslint-disable-next-line no-eq-null
// If we disposed every frame including first frame up to this point, then we have if (this.disposal_restore_from_idx != null) {
// no composited frame to restore to. In this case, restore to background instead. offscreenContext.putImageData(this.frames[this.disposal_restore_from_idx].data, 0, 0);
if (this.disposal_restore_from_idx !== null) {
this.frame.putImageData(this.frames[this.disposal_restore_from_idx].data, 0, 0);
} else {
this.frame.clearRect(
this.last_img.leftPos,
this.last_img.topPos,
this.last_img.width,
this.last_img.height
);
} }
} else { } else {
this.disposal_restore_from_idx = currIdx - 1; this.disposal_restore_from_idx = i - 1;
}
if (this.last_disposal_method === 2) {
// Restore to background color
// Browser implementations historically restore to transparent; we do the same.
// http://www.wizards-toolkit.org/discourse-server/viewtopic.php?f=1&t=21172#p86079
this.frame.clearRect(
this.last_img.leftPos,
this.last_img.topPos,
this.last_img.width,
this.last_img.height
);
} }
} }
// else, Undefined/Do not dispose.
// frame contains final pixel data from the last frame; do nothing
//Get existing pixels for img region after applying disposal method if (disposal === 2) {
const imgData = this.frame.getImageData(img.leftPos, img.topPos, img.width, img.height); // Restore to background color
// Browser implementations historically restore to transparent; we do the same.
//apply color table colors // http://www.wizards-toolkit.org/discourse-server/viewtopic.php?f=1&t=21172#p86079
img.pixels.forEach((pixel, i) => { offscreenContext.clearRect(
// imgData.data === [R,G,B,A,R,G,B,A,...] this.last_frame.dims.left,
if (pixel !== this.transparency) { this.last_frame.dims.top,
imgData.data[i * 4 + 0] = ct[pixel][0]; this.last_frame.dims.width,
imgData.data[i * 4 + 1] = ct[pixel][1]; this.last_frame.dims.height
imgData.data[i * 4 + 2] = ct[pixel][2]; );
imgData.data[i * 4 + 3] = 255; // Opaque.
}
});
this.frame.putImageData(imgData, img.leftPos, img.topPos);
if (!this.ctx_scaled) {
this.ctx.scale(this.getCanvasScale(), this.getCanvasScale());
this.ctx_scaled = true;
} }
if (!this.last_img) {
// This is the first received image, so we draw it
this.ctx.drawImage(this.offscreenCanvas, 0, 0);
}
this.last_img = img;
} }
/** /**
* Draws a gif frame at a specific index inside the canvas. * Draws a gif frame at a specific index inside the canvas.
* @param { Number } i - The frame index * @param {boolean} show_pause_on_hover - The frame index
*/ */
putFrame (i, show_pause_on_hover=true) { renderImage (show_pause_on_hover = true) {
if (!this.frames.length) return if (!this.frames.length) return;
i = parseInt(i, 10); let i = this.frame_idx;
i = parseInt(i.toString(), 10);
if (i > this.frames.length - 1 || i < 0) { if (i > this.frames.length - 1 || i < 0) {
i = 0; i = 0;
} }
const offset = this.frame_offsets[i];
this.offscreenCanvas.getContext('2d').putImageData(this.frames[i].data, offset.x, offset.y); this.manageDisposal(i);
this.ctx.globalCompositeOperation = 'copy';
this.ctx.drawImage(this.offscreenCanvas, 0, 0); const frame = this.frames[i];
const patchContext = this.patchCanvas.getContext('2d');
const offscreenContext = this.offscreenCanvas.getContext('2d');
const dims = frame.dims;
if (
!this.frameImageData ||
dims.width != this.frameImageData.width ||
dims.height != this.frameImageData.height
) {
this.patchCanvas.width = dims.width;
this.patchCanvas.height = dims.height;
this.frameImageData = patchContext.createImageData(dims.width, dims.height);
}
// set the patch data as an override
this.frameImageData.data.set(frame.patch);
// draw the patch back over the canvas
patchContext.putImageData(this.frameImageData, 0, 0);
offscreenContext.drawImage(this.patchCanvas, dims.left, dims.top);
const imageData = offscreenContext.getImageData(0, 0, this.offscreenCanvas.width, this.offscreenCanvas.height);
this.ctx.putImageData(imageData, 0, 0);
this.ctx.drawImage(this.canvas, 0, 0, this.canvas.width, this.canvas.height);
if (show_pause_on_hover && this.hovering) { if (show_pause_on_hover && this.hovering) {
this.drawPauseIcon(); this.drawPauseIcon();
} }
}
clear () { this.last_frame = frame;
this.transparency = null;
this.last_disposal_method = this.disposal_method;
this.disposal_method = null;
this.frame = null;
} }
/** /**
@ -423,7 +319,7 @@ export default class ConverseGif {
*/ */
play () { play () {
this.playing = true; this.playing = true;
requestAnimationFrame(ts => this.onAnimationFrame(ts, 0, 0)); requestAnimationFrame((ts) => this.onAnimationFrame(ts, 0, 0));
} }
/** /**
@ -431,113 +327,74 @@ export default class ConverseGif {
*/ */
pause () { pause () {
this.playing = false; this.playing = false;
requestAnimationFrame(() => this.drawPlayIcon()) requestAnimationFrame(() => this.drawPlayIcon());
} }
drawPauseIcon () { drawPauseIcon () {
if (!this.playing) { if (!this.playing) return;
return;
}
// Clear the potential play button by re-rendering the current frame
this.putFrame(this.frame_idx, false);
this.ctx.globalCompositeOperation = 'source-over'; // Clear the potential play button by re-rendering the current frame
this.renderImage(false);
// Draw dark overlay // Draw dark overlay
this.ctx.fillStyle = 'rgb(0, 0, 0, 0.25)'; this.ctx.fillStyle = 'rgb(0, 0, 0, 0.25)';
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
const icon_size = this.canvas.height*0.1; const icon_size = this.canvas.height * 0.1;
// Draw bars // Draw bars
this.ctx.lineWidth = this.canvas.height*0.04; this.ctx.lineWidth = this.canvas.height * 0.04;
this.ctx.beginPath(); this.ctx.beginPath();
this.ctx.moveTo(this.canvas.width/2-icon_size/2, this.canvas.height/2-icon_size); this.ctx.moveTo(this.canvas.width / 2 - icon_size / 2, this.canvas.height / 2 - icon_size);
this.ctx.lineTo(this.canvas.width/2-icon_size/2, this.canvas.height/2+icon_size); this.ctx.lineTo(this.canvas.width / 2 - icon_size / 2, this.canvas.height / 2 + icon_size);
this.ctx.fillStyle = 'rgb(200, 200, 200, 0.75)'; this.ctx.fillStyle = 'rgb(200, 200, 200, 0.75)';
this.ctx.stroke(); this.ctx.stroke();
this.ctx.beginPath(); this.ctx.beginPath();
this.ctx.moveTo(this.canvas.width/2+icon_size/2, this.canvas.height/2-icon_size); this.ctx.moveTo(this.canvas.width / 2 + icon_size / 2, this.canvas.height / 2 - icon_size);
this.ctx.lineTo(this.canvas.width/2+icon_size/2, this.canvas.height/2+icon_size); this.ctx.lineTo(this.canvas.width / 2 + icon_size / 2, this.canvas.height / 2 + icon_size);
this.ctx.fillStyle = 'rgb(200, 200, 200, 0.75)'; this.ctx.fillStyle = 'rgb(200, 200, 200, 0.75)';
this.ctx.stroke(); this.ctx.stroke();
// Draw circle // Draw circle
this.ctx.lineWidth = this.canvas.height*0.02; this.ctx.lineWidth = this.canvas.height * 0.02;
this.ctx.strokeStyle = 'rgb(200, 200, 200, 0.75)'; this.ctx.strokeStyle = 'rgb(200, 200, 200, 0.75)';
this.ctx.beginPath(); this.ctx.beginPath();
this.ctx.arc( this.ctx.arc(this.canvas.width / 2, this.canvas.height / 2, icon_size * 1.5, 0, 2 * Math.PI);
this.canvas.width/2,
this.canvas.height/2,
icon_size*1.5,
0,
2*Math.PI
);
this.ctx.stroke(); this.ctx.stroke();
} }
drawPlayIcon () { drawPlayIcon () {
if (this.playing) { if (this.playing) return;
return;
}
// Clear the potential pause button by re-rendering the current frame // Clear the potential pause button by re-rendering the current frame
this.putFrame(this.frame_idx, false); this.renderImage(false);
this.ctx.globalCompositeOperation = 'source-over';
// Draw dark overlay // Draw dark overlay
this.ctx.fillStyle = 'rgb(0, 0, 0, 0.25)'; this.ctx.fillStyle = 'rgb(0, 0, 0, 0.25)';
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
// Draw triangle // Draw triangle
const triangle_size = this.canvas.height*0.1; const triangle_size = this.canvas.height * 0.1;
const region = new Path2D(); const region = new Path2D();
region.moveTo(this.canvas.width/2+triangle_size, this.canvas.height/2); // start at the pointy end region.moveTo(this.canvas.width / 2 + triangle_size, this.canvas.height / 2); // start at the pointy end
region.lineTo(this.canvas.width/2-triangle_size/2, this.canvas.height/2+triangle_size); region.lineTo(this.canvas.width / 2 - triangle_size / 2, this.canvas.height / 2 + triangle_size);
region.lineTo(this.canvas.width/2-triangle_size/2, this.canvas.height/2-triangle_size); region.lineTo(this.canvas.width / 2 - triangle_size / 2, this.canvas.height / 2 - triangle_size);
region.closePath(); region.closePath();
this.ctx.fillStyle = 'rgb(200, 200, 200, 0.75)'; this.ctx.fillStyle = 'rgb(200, 200, 200, 0.75)';
this.ctx.fill(region); this.ctx.fill(region);
// Draw circle // Draw circle
const circle_size = triangle_size*1.5; const circle_size = triangle_size * 1.5;
this.ctx.lineWidth = this.canvas.height*0.02; this.ctx.lineWidth = this.canvas.height * 0.02;
this.ctx.strokeStyle = 'rgb(200, 200, 200, 0.75)'; this.ctx.strokeStyle = 'rgb(200, 200, 200, 0.75)';
this.ctx.beginPath(); this.ctx.beginPath();
this.ctx.arc( this.ctx.arc(this.canvas.width / 2, this.canvas.height / 2, circle_size, 0, 2 * Math.PI);
this.canvas.width/2,
this.canvas.height/2,
circle_size,
0,
2*Math.PI
);
this.ctx.stroke(); this.ctx.stroke();
} }
doDecodeProgress (stream, draw) {
this.doShowProgress(stream.pos, stream.data.length, draw);
}
/**
* @param{boolean=} draw Whether to draw progress bar or not;
* this is not idempotent because of translucency.
* Note that this means that the text will be unsynchronized
* with the progress bar on non-frames;
* but those are typically so small (GCE etc.) that it doesn't really matter
*/
withProgress (stream, fn, draw) {
return block => {
fn?.(block);
this.doDecodeProgress(stream, draw);
};
}
getCanvasScale () { getCanvasScale () {
let scale; let scale;
if (this.options.max_width && this.hdr && this.hdr.width > this.options.max_width) { if (this.options.max_width && this.hdr && this.lsd.width > this.options.max_width) {
scale = this.options.max_width / this.hdr.width; scale = this.options.max_width / this.lsd.width;
} else { } else {
scale = 1; scale = 1;
} }
@ -547,22 +404,28 @@ export default class ConverseGif {
/** /**
* Makes an HTTP request to fetch a GIF * Makes an HTTP request to fetch a GIF
* @param { String } url * @param { String } url
* @returns { Promise<String> } Returns a promise which resolves with the response data. * @returns { Promise<ArrayBuffer> } Returns a promise which resolves with the response data.
*/ */
fetchGIF (url) { fetchGIF (url) {
const promise = getOpenPromise(); const promise = getOpenPromise();
const h = new XMLHttpRequest(); const h = new XMLHttpRequest();
h.open('GET', url, true); h.open('GET', url, true);
h.responseType = 'arraybuffer';
h?.overrideMimeType('text/plain; charset=x-user-defined'); h?.overrideMimeType('text/plain; charset=x-user-defined');
h.onload = () => { h.onload = () => {
if (h.status != 200) { if (h.status != 200) {
this.showError('xhr - response'); this.showError();
return promise.reject(); return promise.reject();
} }
promise.resolve(h.response); promise.resolve(h.response);
}; };
h.onprogress = (e) => (e.lengthComputable && this.doShowProgress(e.loaded, e.total, true)); h.onprogress = (e) => e.lengthComputable && this.doShowProgress(e.loaded, e.total, true);
h.onerror = () => this.showError('xhr'); h.onerror = (e) => {
log.error(e);
this.showError();
};
h.send(); h.send();
return promise; return promise;
} }

View File

@ -1,319 +0,0 @@
/**
* @copyright Shachaf Ben-Kiki and the Converse.js contributors
* @description
* Started as a fork of Shachaf Ben-Kiki's jsgif library
* https://github.com/shachaf/jsgif
* @license MIT License
*/
function bitsToNum (ba) {
return ba.reduce(function (s, n) {
return s * 2 + n;
}, 0);
}
function byteToBitArr (bite) {
const a = [];
for (let i = 7; i >= 0; i--) {
a.push( !! (bite & (1 << i)));
}
return a;
}
function lzwDecode (minCodeSize, data) {
// TODO: Now that the GIF parser is a bit different, maybe this should get an array of bytes instead of a String?
let pos = 0; // Maybe this streaming thing should be merged with the Stream?
function readCode (size) {
let code = 0;
for (let i = 0; i < size; i++) {
if (data.charCodeAt(pos >> 3) & (1 << (pos & 7))) {
code |= 1 << i;
}
pos++;
}
return code;
}
const output = [];
const clearCode = 1 << minCodeSize;
const eoiCode = clearCode + 1;
let codeSize = minCodeSize + 1;
let dict = [];
const clear = function () {
dict = [];
codeSize = minCodeSize + 1;
for (let i = 0; i < clearCode; i++) {
dict[i] = [i];
}
dict[clearCode] = [];
dict[eoiCode] = null;
};
let code = clearCode;
let last;
clear();
while (true) { // eslint-disable-line no-constant-condition
last = code;
code = readCode(codeSize);
if (code === clearCode) {
clear();
continue;
}
if (code === eoiCode) break;
if (code < dict.length) {
if (last !== clearCode) {
dict.push(dict[last].concat(dict[code][0]));
}
}
else {
if (code !== dict.length) throw new Error('Invalid LZW code.');
dict.push(dict[last].concat(dict[last][0]));
}
output.push.apply(output, dict[code]);
if (dict.length === (1 << codeSize) && codeSize < 12) {
// If we're at the last code and codeSize is 12, the next code will be a clearCode, and it'll be 12 bits long.
codeSize++;
}
}
// I don't know if this is technically an error, but some GIFs do it.
//if (Math.ceil(pos / 8) !== data.length) throw new Error('Extraneous LZW bytes.');
return output;
}
function readSubBlocks (st) {
let size, data;
data = '';
do {
size = st.readByte();
data += st.read(size);
} while (size !== 0);
return data;
}
/**
* Parses GIF image color table information
* @param { Stream } st
* @param { Number } entries
*/
function parseCT (st, entries) { // Each entry is 3 bytes, for RGB.
const ct = [];
for (let i = 0; i < entries; i++) {
ct.push(st.readBytes(3));
}
return ct;
}
/**
* Parses GIF image information
* @param { Stream } st
* @param { ByteStream } img
* @param { Function } [callback]
*/
function parseImg (st, img, callback) {
function deinterlace (pixels, width) {
// Of course this defeats the purpose of interlacing. And it's *probably*
// the least efficient way it's ever been implemented. But nevertheless...
const newPixels = new Array(pixels.length);
const rows = pixels.length / width;
function cpRow (toRow, fromRow) {
const fromPixels = pixels.slice(fromRow * width, (fromRow + 1) * width);
newPixels.splice.apply(newPixels, [toRow * width, width].concat(fromPixels));
}
// See appendix E.
const offsets = [0, 4, 2, 1];
const steps = [8, 8, 4, 2];
let fromRow = 0;
for (let pass = 0; pass < 4; pass++) {
for (let toRow = offsets[pass]; toRow < rows; toRow += steps[pass]) {
cpRow(toRow, fromRow)
fromRow++;
}
}
return newPixels;
}
img.leftPos = st.readUnsigned();
img.topPos = st.readUnsigned();
img.width = st.readUnsigned();
img.height = st.readUnsigned();
const bits = byteToBitArr(st.readByte());
img.lctFlag = bits.shift();
img.interlaced = bits.shift();
img.sorted = bits.shift();
img.reserved = bits.splice(0, 2);
img.lctSize = bitsToNum(bits.splice(0, 3));
if (img.lctFlag) {
img.lct = parseCT(st, 1 << (img.lctSize + 1));
}
img.lzwMinCodeSize = st.readByte();
const lzwData = readSubBlocks(st);
img.pixels = lzwDecode(img.lzwMinCodeSize, lzwData);
if (img.interlaced) { // Move
img.pixels = deinterlace(img.pixels, img.width);
}
callback?.(img);
}
/**
* Parses GIF header information
* @param { Stream } st
* @param { Function } [callback]
*/
function parseHeader (st, callback) {
const hdr = {};
hdr.sig = st.read(3);
hdr.ver = st.read(3);
if (hdr.sig !== 'GIF') {
throw new Error('Not a GIF file.');
}
hdr.width = st.readUnsigned();
hdr.height = st.readUnsigned();
const bits = byteToBitArr(st.readByte());
hdr.gctFlag = bits.shift();
hdr.colorRes = bitsToNum(bits.splice(0, 3));
hdr.sorted = bits.shift();
hdr.gctSize = bitsToNum(bits.splice(0, 3));
hdr.bgColor = st.readByte();
hdr.pixelAspectRatio = st.readByte(); // if not 0, aspectRatio = (pixelAspectRatio + 15) / 64
if (hdr.gctFlag) {
hdr.gct = parseCT(st, 1 << (hdr.gctSize + 1));
}
callback?.(hdr);
}
function parseExt (st, block, handler) {
function parseGCExt (block) {
st.readByte(); // blocksize, always 4
const bits = byteToBitArr(st.readByte());
block.reserved = bits.splice(0, 3); // Reserved; should be 000.
block.disposalMethod = bitsToNum(bits.splice(0, 3));
block.userInput = bits.shift();
block.transparencyGiven = bits.shift();
block.delayTime = st.readUnsigned();
block.transparencyIndex = st.readByte();
block.terminator = st.readByte();
handler?.gce(block);
}
function parseComExt (block) {
block.comment = readSubBlocks(st);
handler.com && handler.com(block);
}
function parsePTExt (block) {
// No one *ever* uses this. If you use it, deal with parsing it yourself.
st.readByte(); // blocksize, always 12
block.ptHeader = st.readBytes(12);
block.ptData = readSubBlocks(st);
handler.pte && handler.pte(block);
}
function parseAppExt (block) {
function parseNetscapeExt (block) {
st.readByte(); // blocksize, always 3
block.unknown = st.readByte(); // ??? Always 1? What is this?
block.iterations = st.readUnsigned();
block.terminator = st.readByte();
handler.app && handler.app.NETSCAPE && handler.app.NETSCAPE(block);
}
function parseUnknownAppExt (block) {
block.appData = readSubBlocks(st);
// FIXME: This won't work if a handler wants to match on any identifier.
handler.app && handler.app[block.identifier] && handler.app[block.identifier](block);
}
st.readByte(); // blocksize, always 11
block.identifier = st.read(8);
block.authCode = st.read(3);
switch (block.identifier) {
case 'NETSCAPE':
parseNetscapeExt(block);
break;
default:
parseUnknownAppExt(block);
break;
}
}
function parseUnknownExt (block) {
block.data = readSubBlocks(st);
handler.unknown && handler.unknown(block);
}
block.label = st.readByte();
switch (block.label) {
case 0xF9:
block.extType = 'gce';
parseGCExt(block);
break;
case 0xFE:
block.extType = 'com';
parseComExt(block);
break;
case 0x01:
block.extType = 'pte';
parsePTExt(block);
break;
case 0xFF:
block.extType = 'app';
parseAppExt(block);
break;
default:
block.extType = 'unknown';
parseUnknownExt(block);
break;
}
}
/**
* @param { Stream } st
* @param { GIFParserHandlers } handler
*/
function parseBlock (st, handler) {
const block = {}
block.sentinel = st.readByte();
switch (String.fromCharCode(block.sentinel)) { // For ease of matching
case '!':
block.type = 'ext';
parseExt(st, block, handler);
break;
case ',':
block.type = 'img';
parseImg(st, block, handler?.img);
break;
case ';':
block.type = 'eof';
handler?.eof(block);
break;
default:
throw new Error('Unknown block: 0x' + block.sentinel.toString(16)); // TODO: Pad this with a 0.
}
if (block.type !== 'eof') setTimeout(() => parseBlock(st, handler), 0);
}
/**
* Takes a Stream and parses it for GIF data, calling the relevant handler
* methods on the passed in `handler` object.
* @param { Stream } st
* @param { GIFParserHandlers } handler
*/
export function parseGIF (st, handler={}) {
parseHeader(st, handler?.hdr);
setTimeout(() => parseBlock(st, handler), 0);
}

View File

@ -283,11 +283,6 @@ export class RichText extends String {
/** /**
* Parse the text and add template references for rendering the "rich" parts. * Parse the text and add template references for rendering the "rich" parts.
*
* @param { RichText } text
* @param { Boolean } show_images - Should URLs of images be rendered as `<img>` tags?
* @param { Function } onImgLoad
* @param { Function } onImgClick
**/ **/
async addTemplates () { async addTemplates () {
/** /**

View File

@ -50,8 +50,10 @@
.brand-heading { .brand-heading {
display: inline-flex; display: inline-flex;
flex-direction: row; flex-direction: column;
align-items: flex-start; flex-wrap: wrap;
justify-content: center;
align-items: center;
font-family: var(--branding-font); font-family: var(--branding-font);
color: var(--link-color); color: var(--link-color);
margin-bottom: 0.75em; margin-bottom: 0.75em;
@ -67,7 +69,6 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
margin-top: -0.25em;
.byline { .byline {
font-family: var(--heading-font); font-family: var(--heading-font);
@ -119,7 +120,7 @@
font-family: var(--heading-font); font-family: var(--heading-font);
font-size: 0.25em; font-size: 0.25em;
opacity: 0.55; opacity: 0.55;
margin-left: -7em; max-width: 350px;
word-spacing: 5px; word-spacing: 5px;
} }
} }

View File

@ -32,7 +32,6 @@
} }
.badge-secondary { .badge-secondary {
color: white;
background-color: var(--secondary-color); background-color: var(--secondary-color);
border-color: var(--secondary-color); border-color: var(--secondary-color);
&:hover { &:hover {

View File

@ -236,14 +236,20 @@ u.getLastChildElement = function (el, selector = '*') {
return last_el; return last_el;
}; };
u.hasClass = function (className, el) {
return el instanceof Element && el.classList.contains(className);
};
u.toggleClass = function (className, el) { u.toggleClass = function (className, el) {
u.hasClass(className, el) ? removeClass(className, el) : addClass(className, el); u.hasClass(className, el) ? removeClass(className, el) : addClass(className, el);
}; };
/**
* Has an element a class?
* @method u#hasClass
* @param { string } className
* @param { Element } el
*/
export function hasClass (className, el) {
return el instanceof Element && el.classList.contains(className);
}
/** /**
* Add a class to an element. * Add a class to an element.
* @method u#addClass * @method u#addClass
@ -615,6 +621,7 @@ u.xForm2TemplateResult = function (field, stanza, options={}) {
}; };
Object.assign(u, { Object.assign(u, {
hasClass,
addClass, addClass,
ancestor, ancestor,
getOOBURLMarkup, getOOBURLMarkup,

View File

@ -11,6 +11,11 @@
"target": "es2016", "target": "es2016",
"module": "esnext", "module": "esnext",
"lib": [
"ES2020",
"dom"
],
"allowJs": true, "allowJs": true,
"checkJs": true, "checkJs": true,