mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-08-16 14:40:23 +03:00
➡️ Migrate core package 'welcome' into ./packages
This commit is contained in:
parent
3663d59043
commit
f05db285f8
3
package-lock.json
generated
3
package-lock.json
generated
@ -6969,8 +6969,7 @@
|
||||
"integrity": "sha1-BNoCcKh6d4VAFzzb8KLbSZqNnik="
|
||||
},
|
||||
"welcome": {
|
||||
"version": "https://www.atom.io/api/packages/welcome/versions/0.36.9/tarball",
|
||||
"integrity": "sha512-nvDLkdma06bn7DjC4cXvQdm1iTQs0rryNmk6fe44HbqxNyVbmSgNqBjrSllPWPc64C0kAWsgw1PcpVlY/5v4lw==",
|
||||
"version": "file:packages/welcome",
|
||||
"requires": {
|
||||
"etch": "0.9.0"
|
||||
},
|
||||
|
@ -163,7 +163,7 @@
|
||||
"typescript-simple": "1.0.0",
|
||||
"update-package-dependencies": "https://www.atom.io/api/packages/update-package-dependencies/versions/0.13.1/tarball",
|
||||
"vscode-ripgrep": "^1.2.5",
|
||||
"welcome": "https://www.atom.io/api/packages/welcome/versions/0.36.9/tarball",
|
||||
"welcome": "file:packages/welcome",
|
||||
"whitespace": "https://www.atom.io/api/packages/whitespace/versions/0.37.7/tarball",
|
||||
"winreg": "^1.2.1",
|
||||
"wrap-guide": "https://www.atom.io/api/packages/wrap-guide/versions/0.41.0/tarball",
|
||||
@ -226,7 +226,7 @@
|
||||
"timecop": "0.36.2",
|
||||
"tree-view": "0.228.0",
|
||||
"update-package-dependencies": "0.13.1",
|
||||
"welcome": "0.36.9",
|
||||
"welcome": "file:./packages/welcome",
|
||||
"whitespace": "0.37.7",
|
||||
"wrap-guide": "0.41.0",
|
||||
"language-c": "0.60.18",
|
||||
|
@ -97,7 +97,7 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
|
||||
| **timecop** | [`atom/timecop`][timecop] | [#18272](https://github.com/atom/atom/issues/18272) |
|
||||
| **tree-view** | [`atom/tree-view`][tree-view] | |
|
||||
| **update-package-dependencies** | [`atom/update-package-dependencies`][update-package-dependencies] | [#18284](https://github.com/atom/atom/issues/18284) |
|
||||
| **welcome** | [`atom/welcome`][welcome] | [#18285](https://github.com/atom/atom/issues/18285) |
|
||||
| **welcome** | [`./welcome`](./welcome) | [#18285](https://github.com/atom/atom/issues/18285) |
|
||||
| **whitespace** | [`atom/whitespace`][whitespace] | |
|
||||
| **wrap-guide** | [`atom/wrap-guide`][wrap-guide] | [#18286](https://github.com/atom/atom/issues/18286) |
|
||||
|
||||
@ -166,6 +166,5 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate
|
||||
[timecop]: https://github.com/atom/timecop
|
||||
[tree-view]: https://github.com/atom/tree-view
|
||||
[update-package-dependencies]: https://github.com/atom/update-package-dependencies
|
||||
[welcome]: https://github.com/atom/welcome
|
||||
[whitespace]: https://github.com/atom/whitespace
|
||||
[wrap-guide]: https://github.com/atom/wrap-guide
|
||||
|
1
packages/welcome/.gitignore
vendored
Normal file
1
packages/welcome/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules
|
20
packages/welcome/LICENSE.md
Normal file
20
packages/welcome/LICENSE.md
Normal file
@ -0,0 +1,20 @@
|
||||
Copyright (c) 2014 GitHub Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
3
packages/welcome/README.md
Normal file
3
packages/welcome/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
## Welcome package
|
||||
|
||||
Opens a welcome editor with helpful information the very first time Atom is opened and the usage statistics opt-in.
|
28
packages/welcome/assets/code.svg
Normal file
28
packages/welcome/assets/code.svg
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="160px" height="80px" viewBox="0 0 160 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs></defs>
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g>
|
||||
<rect fill-opacity="0.081861413" fill="#FFFFFF" x="0" y="0" width="160" height="80"></rect>
|
||||
<rect fill-opacity="0.164600317" fill="#000000" x="40" y="72" width="120" height="8"></rect>
|
||||
<g>
|
||||
<rect fill-opacity="0.161882926" fill="#000000" x="0" y="0" width="40" height="80"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="4" width="24" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="12" width="16" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="20" width="30" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="28" width="21" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="36" width="24" height="4"></rect>
|
||||
</g>
|
||||
<g transform="translate(40.000000, 0.000000)" fill-opacity="0.164600317" fill="#000000">
|
||||
<rect x="60" y="0" width="60" height="8"></rect>
|
||||
<rect x="0" y="0" width="30" height="8"></rect>
|
||||
</g>
|
||||
<g transform="translate(44.000000, 12.000000)">
|
||||
<rect fill="#BB263A" x="0" y="0" width="18" height="4"></rect>
|
||||
<rect fill="#BB263A" x="0" y="8" width="47" height="4"></rect>
|
||||
<rect fill="#BB263A" x="0" y="16" width="31" height="4"></rect>
|
||||
<rect fill="#FF5F74" x="33" y="16" width="2" height="4"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
29
packages/welcome/assets/package.svg
Normal file
29
packages/welcome/assets/package.svg
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="160px" height="80px" viewBox="0 0 160 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs></defs>
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g>
|
||||
<rect fill-opacity="0.081861413" fill="#FFFFFF" x="0" y="0" width="160" height="80"></rect>
|
||||
<rect fill-opacity="0.164600317" fill="#000000" x="40" y="72" width="120" height="8"></rect>
|
||||
<g>
|
||||
<rect fill-opacity="0.161882926" fill="#000000" x="0" y="0" width="40" height="80"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="4" width="24" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="12" width="16" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="20" width="30" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="28" width="21" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="36" width="24" height="4"></rect>
|
||||
</g>
|
||||
<g transform="translate(40.000000, 0.000000)" fill-opacity="0.164600317" fill="#000000">
|
||||
<rect x="60" y="0" width="60" height="8"></rect>
|
||||
<rect x="0" y="0" width="30" height="8"></rect>
|
||||
</g>
|
||||
<g transform="translate(142.000000, 8.000000)">
|
||||
<rect fill="#BB263A" x="0" y="0" width="18" height="64"></rect>
|
||||
<rect fill="#FF5F74" x="2" y="3" width="12" height="2"></rect>
|
||||
<rect fill="#FF5F74" x="2" y="7" width="14" height="2"></rect>
|
||||
<rect fill="#FF5F74" x="2" y="11" width="6" height="2"></rect>
|
||||
<rect fill="#FF5F74" x="2" y="15" width="10" height="2"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
18
packages/welcome/assets/project.svg
Normal file
18
packages/welcome/assets/project.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="160px" height="80px" viewBox="0 0 160 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs></defs>
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g>
|
||||
<rect fill-opacity="0.081861413" fill="#FFFFFF" x="0" y="0" width="160" height="80"></rect>
|
||||
<rect fill="#BB263A" x="0" y="0" width="40" height="80"></rect>
|
||||
<rect fill-opacity="0.164600317" fill="#000000" x="100" y="0" width="60" height="8"></rect>
|
||||
<rect fill-opacity="0.164600317" fill="#000000" x="40" y="0" width="30" height="8"></rect>
|
||||
<rect fill="#FF5F74" x="4" y="4" width="24" height="4"></rect>
|
||||
<rect fill="#FF5F74" x="4" y="12" width="16" height="4"></rect>
|
||||
<rect fill="#FF5F74" x="4" y="20" width="30" height="4"></rect>
|
||||
<rect fill="#FF5F74" x="4" y="28" width="21" height="4"></rect>
|
||||
<rect fill="#FF5F74" x="4" y="36" width="24" height="4"></rect>
|
||||
<rect fill-opacity="0.164600317" fill="#000000" x="40" y="72" width="120" height="8"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
29
packages/welcome/assets/shortcut.svg
Normal file
29
packages/welcome/assets/shortcut.svg
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="160px" height="80px" viewBox="0 0 160 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs></defs>
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g>
|
||||
<rect fill-opacity="0.081861413" fill="#FFFFFF" x="0" y="0" width="160" height="80"></rect>
|
||||
<rect fill-opacity="0.164600317" fill="#000000" x="40" y="72" width="120" height="8"></rect>
|
||||
<g>
|
||||
<rect fill-opacity="0.161882926" fill="#000000" x="0" y="0" width="40" height="80"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="4" width="24" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="12" width="16" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="20" width="30" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="28" width="21" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="36" width="24" height="4"></rect>
|
||||
</g>
|
||||
<g transform="translate(40.000000, 0.000000)" fill-opacity="0.164600317" fill="#000000">
|
||||
<rect x="60" y="0" width="60" height="8"></rect>
|
||||
<rect x="0" y="0" width="30" height="8"></rect>
|
||||
</g>
|
||||
<g transform="translate(56.000000, 0.000000)">
|
||||
<rect fill="#BB263A" x="0" y="0" width="48" height="32"></rect>
|
||||
<rect fill="#FF5F74" x="4" y="4" width="40" height="4"></rect>
|
||||
<rect fill="#FF5F74" x="4" y="12" width="22" height="4"></rect>
|
||||
<rect fill="#FF5F74" x="4" y="18" width="30" height="4"></rect>
|
||||
<rect fill="#FF5F74" x="4" y="24" width="18" height="4"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
24
packages/welcome/assets/theme.svg
Normal file
24
packages/welcome/assets/theme.svg
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="160px" height="80px" viewBox="0 0 160 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs></defs>
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g>
|
||||
<rect fill-opacity="0.081861413" fill="#FFFFFF" x="0" y="0" width="160" height="80"></rect>
|
||||
<rect fill-opacity="0.164600317" fill="#000000" x="40" y="72" width="120" height="8"></rect>
|
||||
<g>
|
||||
<rect fill-opacity="0.161882926" fill="#000000" x="0" y="0" width="40" height="80"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="4" width="24" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="12" width="16" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="20" width="30" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="28" width="21" height="4"></rect>
|
||||
<rect fill-opacity="0.08" fill="#FFFFFF" x="4" y="36" width="24" height="4"></rect>
|
||||
</g>
|
||||
<g transform="translate(40.000000, 0.000000)" fill-opacity="0.164600317" fill="#000000">
|
||||
<rect x="60" y="0" width="60" height="8"></rect>
|
||||
<rect x="0" y="0" width="30" height="8"></rect>
|
||||
</g>
|
||||
<path d="M140,0 L160,0 L160,80 L20,80 L140,0 Z" fill="#BB263A"></path>
|
||||
<path d="M128,8 L160,8 L160,72 L39.984375,72 L39.984375,66.6474609 L128,8 Z" fill="#FF5F75"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
36
packages/welcome/docs/events.md
Normal file
36
packages/welcome/docs/events.md
Normal file
@ -0,0 +1,36 @@
|
||||
# Events specification
|
||||
|
||||
This document specifies all the data (along with the format) which gets sent from the Welcome package to the GitHub analytics pipeline. This document follows the same format and nomenclature as the [Atom Core Events spec](https://github.com/atom/metrics/blob/master/docs/events.md).
|
||||
|
||||
## Counters
|
||||
|
||||
Currently the Welcome package does not log any counter events.
|
||||
|
||||
## Timing events
|
||||
|
||||
Currently the Welcome package does not log any timing events.
|
||||
|
||||
## Standard events
|
||||
|
||||
#### Welcome package shown
|
||||
|
||||
* **eventType**: `welcome-v1`
|
||||
* **metadata**
|
||||
|
||||
| field | value |
|
||||
|-------|-------|
|
||||
| `ea` | `show-on-initial-load`
|
||||
|
||||
|
||||
#### Click on links
|
||||
|
||||
* **eventType**: `welcome-v1`
|
||||
* **metadata**
|
||||
|
||||
| field | value |
|
||||
|-------|-------|
|
||||
| `ea` | link that was clicked
|
||||
|
||||
(There are many potential values for the `ea` param, e.g: `clicked-welcome-atom-docs-link`,`clicked-welcome-atom-org-link`, `clicked-project-cta`, `clicked-init-script-cta`, ...).
|
||||
|
||||
|
92
packages/welcome/lib/consent-view.js
Normal file
92
packages/welcome/lib/consent-view.js
Normal file
@ -0,0 +1,92 @@
|
||||
'use babel'
|
||||
/** @jsx etch.dom */
|
||||
|
||||
import etch from 'etch'
|
||||
|
||||
export default class ConsentView {
|
||||
constructor () {
|
||||
etch.initialize(this)
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className='welcome'>
|
||||
<div className='welcome-container'>
|
||||
<div className='header'>
|
||||
<a title='atom.io' href='https://atom.io/'>
|
||||
<svg class='welcome-logo' width='330px' height='68px' viewBox='0 0 330 68' version='1.1'>
|
||||
<g stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'>
|
||||
<g transform='translate(2.000000, 1.000000)'>
|
||||
<g transform='translate(96.000000, 8.000000)' fill='currentColor'>
|
||||
<path d='M185.498,3.399 C185.498,2.417 186.34,1.573 187.324,1.573 L187.674,1.573 C188.447,1.573 189.01,1.995 189.5,2.628 L208.676,30.862 L227.852,2.628 C228.272,1.995 228.905,1.573 229.676,1.573 L230.028,1.573 C231.01,1.573 231.854,2.417 231.854,3.399 L231.854,49.403 C231.854,50.387 231.01,51.231 230.028,51.231 C229.044,51.231 228.202,50.387 228.202,49.403 L228.202,8.246 L210.151,34.515 C209.729,35.148 209.237,35.428 208.606,35.428 C207.973,35.428 207.481,35.148 207.061,34.515 L189.01,8.246 L189.01,49.475 C189.01,50.457 188.237,51.231 187.254,51.231 C186.27,51.231 185.498,50.458 185.498,49.475 L185.498,3.399 L185.498,3.399 Z' />
|
||||
<path d='M113.086,26.507 L113.086,26.367 C113.086,12.952 122.99,0.941 137.881,0.941 C152.77,0.941 162.533,12.811 162.533,26.225 L162.533,26.367 C162.533,39.782 152.629,51.792 137.74,51.792 C122.85,51.792 113.086,39.923 113.086,26.507 M158.74,26.507 L158.74,26.367 C158.74,14.216 149.89,4.242 137.74,4.242 C125.588,4.242 116.879,14.075 116.879,26.225 L116.879,26.367 C116.879,38.518 125.729,48.491 137.881,48.491 C150.031,48.491 158.74,38.658 158.74,26.507' />
|
||||
<path d='M76.705,5.155 L60.972,5.155 C60.06,5.155 59.287,4.384 59.287,3.469 C59.287,2.556 60.059,1.783 60.972,1.783 L96.092,1.783 C97.004,1.783 97.778,2.555 97.778,3.469 C97.778,4.383 97.005,5.155 96.092,5.155 L80.358,5.155 L80.358,49.405 C80.358,50.387 79.516,51.231 78.532,51.231 C77.55,51.231 76.706,50.387 76.706,49.405 L76.706,5.155 L76.705,5.155 Z' />
|
||||
<path d='M0.291,48.562 L21.291,3.05 C21.783,1.995 22.485,1.292 23.75,1.292 L23.891,1.292 C25.155,1.292 25.858,1.995 26.348,3.05 L47.279,48.421 C47.49,48.843 47.56,49.194 47.56,49.546 C47.56,50.458 46.788,51.231 45.803,51.231 C44.961,51.231 44.329,50.599 43.978,49.826 L38.219,37.183 L9.21,37.183 L3.45,49.897 C3.099,50.739 2.538,51.231 1.694,51.231 C0.781,51.231 0.008,50.529 0.008,49.685 C0.009,49.404 0.08,48.983 0.291,48.562 L0.291,48.562 Z M36.673,33.882 L23.749,5.437 L10.755,33.882 L36.673,33.882 L36.673,33.882 Z' />
|
||||
</g>
|
||||
<g>
|
||||
<path d='M40.363,32.075 C40.874,34.44 39.371,36.77 37.006,37.282 C34.641,37.793 32.311,36.29 31.799,33.925 C31.289,31.56 32.791,29.23 35.156,28.718 C37.521,28.207 39.851,29.71 40.363,32.075' fill='currentColor' />
|
||||
<path d='M48.578,28.615 C56.851,45.587 58.558,61.581 52.288,64.778 C45.822,68.076 33.326,56.521 24.375,38.969 C15.424,21.418 13.409,4.518 19.874,1.221 C22.689,-0.216 26.648,1.166 30.959,4.629' stroke='currentColor' stroke-width='3.08' stroke-linecap='round' />
|
||||
<path d='M7.64,39.45 C2.806,36.94 -0.009,33.915 0.154,30.79 C0.531,23.542 16.787,18.497 36.462,19.52 C56.137,20.544 71.781,27.249 71.404,34.497 C71.241,37.622 68.127,40.338 63.06,42.333' stroke='currentColor' stroke-width='3.08' stroke-linecap='round' />
|
||||
<path d='M28.828,59.354 C23.545,63.168 18.843,64.561 15.902,62.653 C9.814,58.702 13.572,42.102 24.296,25.575 C35.02,9.048 48.649,-1.149 54.736,2.803 C57.566,4.639 58.269,9.208 57.133,15.232' stroke='currentColor' stroke-width='3.08' stroke-linecap='round' />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
<div className='welcome-consent'>
|
||||
<p>Help improve Atom by sending your anonymous <strong>usage data</strong> to the Atom team. The resulting data plays a key role in deciding what we focus on next.</p>
|
||||
|
||||
<div className='welcome-consent-choices'>
|
||||
<div>
|
||||
<button className='btn btn-primary' onclick={this.consent.bind(this)}>Yes, send my usage data</button>
|
||||
<p className='welcome-note'>Including exception and crash reports. See the <a onclick={this.openMetricsPackage.bind(this)}>atom/metrics package</a> for more details.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button className='btn btn-primary' onclick={this.decline.bind(this)}>No, do not send my usage data</button>
|
||||
<p className='welcome-note'>Note: We only register anonymously that you opted-out.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='welcome-footer'>
|
||||
<p className='welcome-love'>
|
||||
<span className='icon icon-code' />
|
||||
<span className='inline'> with </span>
|
||||
<span className='icon icon-heart' />
|
||||
<span className='inline'> by </span>
|
||||
<a className='icon icon-logo-github' title='GitHub' href='https://github.com' />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
update () {
|
||||
return etch.update(this)
|
||||
}
|
||||
|
||||
consent () {
|
||||
atom.config.set('core.telemetryConsent', 'limited')
|
||||
atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow()
|
||||
}
|
||||
|
||||
decline () {
|
||||
atom.config.set('core.telemetryConsent', 'no')
|
||||
atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow()
|
||||
}
|
||||
|
||||
openMetricsPackage () {
|
||||
atom.workspace.open('atom://config/packages/metrics')
|
||||
}
|
||||
|
||||
getTitle () {
|
||||
return 'Telemetry Consent'
|
||||
}
|
||||
|
||||
async destroy () {
|
||||
await etch.destroy(this)
|
||||
}
|
||||
}
|
366
packages/welcome/lib/guide-view.js
Normal file
366
packages/welcome/lib/guide-view.js
Normal file
@ -0,0 +1,366 @@
|
||||
/** @babel */
|
||||
/** @jsx etch.dom **/
|
||||
|
||||
import etch from 'etch'
|
||||
|
||||
export default class GuideView {
|
||||
constructor (props) {
|
||||
this.props = props
|
||||
this.didClickProjectButton = this.didClickProjectButton.bind(this)
|
||||
this.didClickGitButton = this.didClickGitButton.bind(this)
|
||||
this.didClickGitHubButton = this.didClickGitHubButton.bind(this)
|
||||
this.didClickTeletypeButton = this.didClickTeletypeButton.bind(this)
|
||||
this.didClickPackagesButton = this.didClickPackagesButton.bind(this)
|
||||
this.didClickThemesButton = this.didClickThemesButton.bind(this)
|
||||
this.didClickStylingButton = this.didClickStylingButton.bind(this)
|
||||
this.didClickInitScriptButton = this.didClickInitScriptButton.bind(this)
|
||||
this.didClickSnippetsButton = this.didClickSnippetsButton.bind(this)
|
||||
this.didExpandOrCollapseSection = this.didExpandOrCollapseSection.bind(this)
|
||||
etch.initialize(this)
|
||||
}
|
||||
|
||||
update () {}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className='welcome is-guide'>
|
||||
<div className='welcome-container'>
|
||||
<section className='welcome-panel'>
|
||||
<h1 className='welcome-title'>
|
||||
Get to know Atom!
|
||||
</h1>
|
||||
|
||||
<details className='welcome-card' {...this.getSectionProps('project')}>
|
||||
<summary className='welcome-summary icon icon-repo'>
|
||||
Open a <span className='welcome-highlight'>Project</span>
|
||||
</summary>
|
||||
<div className='welcome-detail'>
|
||||
<p>
|
||||
<img className='welcome-img' src='atom://welcome/assets/project.svg' />
|
||||
</p>
|
||||
<p>
|
||||
In Atom you can open individual files or a whole folder as a
|
||||
project. Opening a folder will add a tree view to the editor
|
||||
where you can browse all the files.
|
||||
</p>
|
||||
<p>
|
||||
<button ref='projectButton' onclick={this.didClickProjectButton} className='btn btn-primary'>
|
||||
Open a Project
|
||||
</button>
|
||||
</p>
|
||||
<p className='welcome-note'>
|
||||
<strong>Next time:</strong> You can also open projects from
|
||||
the menu, keyboard shortcut or by dragging a folder onto the
|
||||
Atom dock icon.
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details className='welcome-card' {...this.getSectionProps('git')}>
|
||||
<summary className='welcome-summary icon icon-mark-github'>
|
||||
Version control with <span class='welcome-highlight'>Git and GitHub</span>
|
||||
</summary>
|
||||
<div className='welcome-detail'>
|
||||
<p>
|
||||
<img className='welcome-img' src='atom://welcome/assets/package.svg' />
|
||||
</p>
|
||||
<p>
|
||||
Track changes to your code as you work. Branch, commit, push, and pull without leaving
|
||||
the comfort of your editor. Collaborate with other developers on GitHub.
|
||||
</p>
|
||||
<p>
|
||||
<button onclick={this.didClickGitButton} className='btn btn-primary inline-block'>
|
||||
Open the Git panel
|
||||
</button>
|
||||
<button onclick={this.didClickGitHubButton} className='btn btn-primary inline-block'>
|
||||
Open the GitHub panel
|
||||
</button>
|
||||
</p>
|
||||
<p className='welcome-note'>
|
||||
<strong>Next time:</strong> You can toggle the Git tab by clicking on the
|
||||
<span className='icon icon-diff' /> button in your status bar.
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details className='welcome-card' {...this.getSectionProps('teletype')}>
|
||||
<summary className='welcome-summary icon icon-radio-tower'>
|
||||
Collaborate in real time with <span class='welcome-highlight'>Teletype</span>
|
||||
</summary>
|
||||
<div className='welcome-detail'>
|
||||
<p>
|
||||
<img className='welcome-img' src='atom://welcome/assets/code.svg' />
|
||||
</p>
|
||||
<p>
|
||||
Share your workspace with team members and collaborate on code in real time.
|
||||
</p>
|
||||
<p>
|
||||
<button onclick={this.didClickTeletypeButton} className='btn btn-primary inline-block'>
|
||||
Install Teletype for Atom
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details className='welcome-card' {...this.getSectionProps('packages')}>
|
||||
<summary className='welcome-summary icon icon-package'>
|
||||
Install a <span className='welcome-highlight'>Package</span>
|
||||
</summary>
|
||||
<div className='welcome-detail'>
|
||||
<p>
|
||||
<img className='welcome-img' src='atom://welcome/assets/package.svg' />
|
||||
</p>
|
||||
<p>
|
||||
One of the best things about Atom is the package ecosystem.
|
||||
Installing packages adds new features and functionality you
|
||||
can use to make the editor suit your needs. Let's install one.
|
||||
</p>
|
||||
<p>
|
||||
<button ref='packagesButton' onclick={this.didClickPackagesButton} className='btn btn-primary'>
|
||||
Open Installer
|
||||
</button>
|
||||
</p>
|
||||
<p className='welcome-note'>
|
||||
<strong>Next time:</strong> You can install new packages from the settings.
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details className='welcome-card' {...this.getSectionProps('themes')}>
|
||||
<summary className='welcome-summary icon icon-paintcan'>
|
||||
Choose a <span class='welcome-highlight'>Theme</span>
|
||||
</summary>
|
||||
<div className='welcome-detail'>
|
||||
<p>
|
||||
<img className='welcome-img' src='atom://welcome/assets/theme.svg' />
|
||||
</p>
|
||||
<p>
|
||||
Atom comes with preinstalled themes. Let's try a few.
|
||||
</p>
|
||||
<p>
|
||||
<button ref='themesButton' onclick={this.didClickThemesButton} className='btn btn-primary'>
|
||||
Open the theme picker
|
||||
</button>
|
||||
</p>
|
||||
<p>
|
||||
You can also install themes created by the Atom community. To
|
||||
install new themes, click on "+ Install" and switch the toggle
|
||||
to "themes".
|
||||
</p>
|
||||
<p className='welcome-note'>
|
||||
<strong>Next time:</strong> You can switch themes from the settings.
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details className='welcome-card' {...this.getSectionProps('styling')}>
|
||||
<summary className='welcome-summary icon icon-paintcan'>
|
||||
Customize the <span class='welcome-highlight'>Styling</span>
|
||||
</summary>
|
||||
<div className='welcome-detail'>
|
||||
<p>
|
||||
<img className='welcome-img' src='atom://welcome/assets/code.svg' />
|
||||
</p>
|
||||
<p>
|
||||
You can customize almost anything by adding your own CSS/LESS.
|
||||
</p>
|
||||
<p>
|
||||
<button ref='stylingButton' onclick={this.didClickStylingButton} className='btn btn-primary'>
|
||||
Open your Stylesheet
|
||||
</button>
|
||||
</p>
|
||||
<p>
|
||||
Now uncomment some of the examples or try your own
|
||||
</p>
|
||||
<p className='welcome-note'>
|
||||
<strong>Next time:</strong> You can open your stylesheet from Menu {this.getApplicationMenuName()}.
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details className='welcome-card' {...this.getSectionProps('init-script')}>
|
||||
<summary className='welcome-summary icon icon-code'>
|
||||
Hack on the <span class='welcome-highlight'>Init Script</span>
|
||||
</summary>
|
||||
<div className='welcome-detail'>
|
||||
<p>
|
||||
<img className='welcome-img' src='atom://welcome/assets/code.svg' />
|
||||
</p>
|
||||
<p>
|
||||
The init script is a bit of JavaScript or CoffeeScript run at
|
||||
startup. You can use it to quickly change the behaviour of
|
||||
Atom.
|
||||
</p>
|
||||
<p>
|
||||
<button ref='initScriptButton' onclick={this.didClickInitScriptButton} className='btn btn-primary'>
|
||||
Open your Init Script
|
||||
</button>
|
||||
</p>
|
||||
<p>
|
||||
Uncomment some of the examples or try out your own.
|
||||
</p>
|
||||
<p className='welcome-note'>
|
||||
<strong>Next time:</strong> You can open your init script from Menu > {this.getApplicationMenuName()}.
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details className='welcome-card' {...this.getSectionProps('snippets')}>
|
||||
<summary className='welcome-summary icon icon-code'>
|
||||
Add a <span class='welcome-highlight'>Snippet</span>
|
||||
</summary>
|
||||
<div className='welcome-detail'>
|
||||
<p>
|
||||
<img className='welcome-img' src='atom://welcome/assets/code.svg' />
|
||||
</p>
|
||||
<p>
|
||||
Atom snippets allow you to enter a simple prefix in the editor
|
||||
and hit tab to expand the prefix into a larger code block with
|
||||
templated values.
|
||||
</p>
|
||||
<p>
|
||||
<button ref='snippetsButton' onclick={this.didClickSnippetsButton} className='btn btn-primary'>
|
||||
Open your Snippets
|
||||
</button>
|
||||
</p>
|
||||
<p>
|
||||
In your snippets file, type <code>snip</code> then hit <code>tab</code>.
|
||||
The <code>snip</code> snippet will expand
|
||||
to create a snippet!
|
||||
</p>
|
||||
<p className='welcome-note'>
|
||||
<strong>Next time:</strong> You can open your snippets in Menu > {this.getApplicationMenuName()}.
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details className='welcome-card' {...this.getSectionProps('shortcuts')}>
|
||||
<summary className='welcome-summary icon icon-keyboard'>
|
||||
Learn <span class='welcome-highlight'>Keyboard Shortcuts</span>
|
||||
</summary>
|
||||
<div className='welcome-detail'>
|
||||
<p>
|
||||
<img className='welcome-img' src='atom://welcome/assets/shortcut.svg' />
|
||||
</p>
|
||||
<p>
|
||||
If you only remember one keyboard shortcut make
|
||||
it <kbd className='welcome-key'>{this.getCommandPaletteKeyBinding()}</kbd>.
|
||||
This keystroke toggles the command palette, which lists every
|
||||
Atom command. It's a good way to learn more shortcuts. Yes,
|
||||
you can try it now!
|
||||
</p>
|
||||
<p>
|
||||
If you want to use these guides again use the command
|
||||
palette <kbd className='welcome-key'>{this.getCommandPaletteKeyBinding()}</kbd> and
|
||||
search for <span className='text-highlight'>Welcome</span>.
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
getSectionProps (sectionName) {
|
||||
const props = {dataset: {section: sectionName}, onclick: this.didExpandOrCollapseSection}
|
||||
if (this.props.openSections && this.props.openSections.indexOf(sectionName) !== -1) {
|
||||
props.open = true
|
||||
}
|
||||
return props
|
||||
}
|
||||
|
||||
getCommandPaletteKeyBinding () {
|
||||
if (process.platform === 'darwin') {
|
||||
return 'cmd-shift-p'
|
||||
} else {
|
||||
return 'ctrl-shift-p'
|
||||
}
|
||||
}
|
||||
|
||||
getApplicationMenuName () {
|
||||
if (process.platform === 'darwin') {
|
||||
return 'Atom'
|
||||
} else if (process.platform === 'linux') {
|
||||
return 'Edit'
|
||||
} else {
|
||||
return 'File'
|
||||
}
|
||||
}
|
||||
|
||||
serialize () {
|
||||
return {
|
||||
deserializer: this.constructor.name,
|
||||
openSections: this.getOpenSections(),
|
||||
uri: this.getURI()
|
||||
}
|
||||
}
|
||||
|
||||
getURI () {
|
||||
return this.props.uri
|
||||
}
|
||||
|
||||
getTitle () {
|
||||
return 'Welcome Guide'
|
||||
}
|
||||
|
||||
isEqual (other) {
|
||||
return other instanceof GuideView
|
||||
}
|
||||
|
||||
getOpenSections () {
|
||||
return Array.from(this.element.querySelectorAll('details[open]'))
|
||||
.map((sectionElement) => sectionElement.dataset.section)
|
||||
}
|
||||
|
||||
didClickProjectButton () {
|
||||
this.props.reporterProxy.sendEvent('clicked-project-cta')
|
||||
atom.commands.dispatch(atom.views.getView(atom.workspace), 'application:open')
|
||||
}
|
||||
|
||||
didClickGitButton () {
|
||||
this.props.reporterProxy.sendEvent('clicked-git-cta')
|
||||
atom.commands.dispatch(atom.views.getView(atom.workspace), 'github:toggle-git-tab')
|
||||
}
|
||||
|
||||
didClickGitHubButton () {
|
||||
this.props.reporterProxy.sendEvent('clicked-github-cta')
|
||||
atom.commands.dispatch(atom.views.getView(atom.workspace), 'github:toggle-github-tab')
|
||||
}
|
||||
|
||||
didClickPackagesButton () {
|
||||
this.props.reporterProxy.sendEvent('clicked-packages-cta')
|
||||
atom.workspace.open('atom://config/install', {split: 'left'})
|
||||
}
|
||||
|
||||
didClickThemesButton () {
|
||||
this.props.reporterProxy.sendEvent('clicked-themes-cta')
|
||||
atom.workspace.open('atom://config/themes', {split: 'left'})
|
||||
}
|
||||
|
||||
didClickStylingButton () {
|
||||
this.props.reporterProxy.sendEvent('clicked-styling-cta')
|
||||
atom.workspace.open('atom://.atom/stylesheet', {split: 'left'})
|
||||
}
|
||||
|
||||
didClickInitScriptButton () {
|
||||
this.props.reporterProxy.sendEvent('clicked-init-script-cta')
|
||||
atom.workspace.open('atom://.atom/init-script', {split: 'left'})
|
||||
}
|
||||
|
||||
didClickSnippetsButton () {
|
||||
this.props.reporterProxy.sendEvent('clicked-snippets-cta')
|
||||
atom.workspace.open('atom://.atom/snippets', {split: 'left'})
|
||||
}
|
||||
|
||||
didClickTeletypeButton () {
|
||||
this.props.reporterProxy.sendEvent('clicked-teletype-cta')
|
||||
atom.workspace.open('atom://config/packages/teletype', {split: 'left'})
|
||||
}
|
||||
|
||||
didExpandOrCollapseSection (event) {
|
||||
const sectionName = event.currentTarget.closest('details').dataset.section
|
||||
const action = event.currentTarget.hasAttribute('open') ? 'collapse' : 'expand'
|
||||
this.props.reporterProxy.sendEvent(`${action}-${sectionName}-section`)
|
||||
}
|
||||
}
|
5
packages/welcome/lib/main.js
Normal file
5
packages/welcome/lib/main.js
Normal file
@ -0,0 +1,5 @@
|
||||
/** @babel */
|
||||
|
||||
import WelcomePackage from './welcome-package'
|
||||
|
||||
export default new WelcomePackage()
|
27
packages/welcome/lib/reporter-proxy.js
Normal file
27
packages/welcome/lib/reporter-proxy.js
Normal file
@ -0,0 +1,27 @@
|
||||
/** @babel */
|
||||
|
||||
export default class ReporterProxy {
|
||||
constructor () {
|
||||
this.reporter = null
|
||||
this.queue = []
|
||||
this.eventType = 'welcome-v1'
|
||||
}
|
||||
|
||||
setReporter (reporter) {
|
||||
this.reporter = reporter
|
||||
let customEvent
|
||||
|
||||
while ((customEvent = this.queue.shift())) {
|
||||
this.reporter.addCustomEvent(this.eventType, customEvent)
|
||||
}
|
||||
}
|
||||
|
||||
sendEvent (action, label, value) {
|
||||
const event = { ea: action, el: label, ev: value }
|
||||
if (this.reporter) {
|
||||
this.reporter.addCustomEvent(this.eventType, event)
|
||||
} else {
|
||||
this.queue.push(event)
|
||||
}
|
||||
}
|
||||
}
|
81
packages/welcome/lib/welcome-package.js
Normal file
81
packages/welcome/lib/welcome-package.js
Normal file
@ -0,0 +1,81 @@
|
||||
/** @babel */
|
||||
|
||||
import {CompositeDisposable} from 'atom'
|
||||
import ReporterProxy from './reporter-proxy'
|
||||
|
||||
let WelcomeView, GuideView, ConsentView
|
||||
|
||||
const WELCOME_URI = 'atom://welcome/welcome'
|
||||
const GUIDE_URI = 'atom://welcome/guide'
|
||||
const CONSENT_URI = 'atom://welcome/consent'
|
||||
|
||||
export default class WelcomePackage {
|
||||
constructor () {
|
||||
this.reporterProxy = new ReporterProxy()
|
||||
}
|
||||
|
||||
async activate () {
|
||||
this.subscriptions = new CompositeDisposable()
|
||||
|
||||
this.subscriptions.add(atom.workspace.addOpener((filePath) => {
|
||||
if (filePath === WELCOME_URI) {
|
||||
return this.createWelcomeView({uri: WELCOME_URI})
|
||||
}
|
||||
}))
|
||||
|
||||
this.subscriptions.add(atom.workspace.addOpener((filePath) => {
|
||||
if (filePath === GUIDE_URI) {
|
||||
return this.createGuideView({uri: GUIDE_URI})
|
||||
}
|
||||
}))
|
||||
|
||||
this.subscriptions.add(atom.workspace.addOpener((filePath) => {
|
||||
if (filePath === CONSENT_URI) {
|
||||
return this.createConsentView({uri: CONSENT_URI})
|
||||
}
|
||||
}))
|
||||
|
||||
this.subscriptions.add(
|
||||
atom.commands.add('atom-workspace', 'welcome:show', () => this.show())
|
||||
)
|
||||
|
||||
if (atom.config.get('core.telemetryConsent') === 'undecided') {
|
||||
await atom.workspace.open(CONSENT_URI)
|
||||
}
|
||||
|
||||
if (atom.config.get('welcome.showOnStartup')) {
|
||||
await this.show()
|
||||
this.reporterProxy.sendEvent('show-on-initial-load')
|
||||
}
|
||||
}
|
||||
|
||||
show () {
|
||||
return Promise.all([
|
||||
atom.workspace.open(WELCOME_URI, {split: 'left'}),
|
||||
atom.workspace.open(GUIDE_URI, {split: 'right'})
|
||||
])
|
||||
}
|
||||
|
||||
consumeReporter (reporter) {
|
||||
return this.reporterProxy.setReporter(reporter)
|
||||
}
|
||||
|
||||
deactivate () {
|
||||
this.subscriptions.dispose()
|
||||
}
|
||||
|
||||
createWelcomeView (state) {
|
||||
if (WelcomeView == null) WelcomeView = require('./welcome-view')
|
||||
return new WelcomeView({reporterProxy: this.reporterProxy, ...state})
|
||||
}
|
||||
|
||||
createGuideView (state) {
|
||||
if (GuideView == null) GuideView = require('./guide-view')
|
||||
return new GuideView({reporterProxy: this.reporterProxy, ...state})
|
||||
}
|
||||
|
||||
createConsentView (state) {
|
||||
if (ConsentView == null) ConsentView = require('./consent-view')
|
||||
return new ConsentView({reporterProxy: this.reporterProxy, ...state})
|
||||
}
|
||||
}
|
97
packages/welcome/lib/welcome-view.js
Normal file
97
packages/welcome/lib/welcome-view.js
Normal file
@ -0,0 +1,97 @@
|
||||
/** @babel */
|
||||
/** @jsx etch.dom **/
|
||||
|
||||
import etch from 'etch'
|
||||
|
||||
export default class WelcomeView {
|
||||
constructor (props) {
|
||||
this.props = props
|
||||
etch.initialize(this)
|
||||
|
||||
this.element.addEventListener('click', (event) => {
|
||||
const link = event.target.closest('a')
|
||||
if (link && link.dataset.event) {
|
||||
this.props.reporterProxy.sendEvent(`clicked-welcome-${link.dataset.event}-link`)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
didChangeShowOnStartup () {
|
||||
atom.config.set('welcome.showOnStartup', this.checked)
|
||||
}
|
||||
|
||||
update () {}
|
||||
|
||||
serialize () {
|
||||
return {
|
||||
deserializer: 'WelcomeView',
|
||||
uri: this.props.uri
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div className='welcome'>
|
||||
<div className='welcome-container'>
|
||||
<header className='welcome-header'>
|
||||
<a href='https://atom.io/'>
|
||||
<svg className='welcome-logo' width='330px' height='68px' viewBox='0 0 330 68' version='1.1'>
|
||||
<g stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'>
|
||||
<g transform='translate(2.000000, 1.000000)'>
|
||||
<g transform='translate(96.000000, 8.000000)' fill='currentColor'>
|
||||
<path d='M185.498,3.399 C185.498,2.417 186.34,1.573 187.324,1.573 L187.674,1.573 C188.447,1.573 189.01,1.995 189.5,2.628 L208.676,30.862 L227.852,2.628 C228.272,1.995 228.905,1.573 229.676,1.573 L230.028,1.573 C231.01,1.573 231.854,2.417 231.854,3.399 L231.854,49.403 C231.854,50.387 231.01,51.231 230.028,51.231 C229.044,51.231 228.202,50.387 228.202,49.403 L228.202,8.246 L210.151,34.515 C209.729,35.148 209.237,35.428 208.606,35.428 C207.973,35.428 207.481,35.148 207.061,34.515 L189.01,8.246 L189.01,49.475 C189.01,50.457 188.237,51.231 187.254,51.231 C186.27,51.231 185.498,50.458 185.498,49.475 L185.498,3.399 L185.498,3.399 Z' />
|
||||
<path d='M113.086,26.507 L113.086,26.367 C113.086,12.952 122.99,0.941 137.881,0.941 C152.77,0.941 162.533,12.811 162.533,26.225 L162.533,26.367 C162.533,39.782 152.629,51.792 137.74,51.792 C122.85,51.792 113.086,39.923 113.086,26.507 M158.74,26.507 L158.74,26.367 C158.74,14.216 149.89,4.242 137.74,4.242 C125.588,4.242 116.879,14.075 116.879,26.225 L116.879,26.367 C116.879,38.518 125.729,48.491 137.881,48.491 C150.031,48.491 158.74,38.658 158.74,26.507' />
|
||||
<path d='M76.705,5.155 L60.972,5.155 C60.06,5.155 59.287,4.384 59.287,3.469 C59.287,2.556 60.059,1.783 60.972,1.783 L96.092,1.783 C97.004,1.783 97.778,2.555 97.778,3.469 C97.778,4.383 97.005,5.155 96.092,5.155 L80.358,5.155 L80.358,49.405 C80.358,50.387 79.516,51.231 78.532,51.231 C77.55,51.231 76.706,50.387 76.706,49.405 L76.706,5.155 L76.705,5.155 Z' />
|
||||
<path d='M0.291,48.562 L21.291,3.05 C21.783,1.995 22.485,1.292 23.75,1.292 L23.891,1.292 C25.155,1.292 25.858,1.995 26.348,3.05 L47.279,48.421 C47.49,48.843 47.56,49.194 47.56,49.546 C47.56,50.458 46.788,51.231 45.803,51.231 C44.961,51.231 44.329,50.599 43.978,49.826 L38.219,37.183 L9.21,37.183 L3.45,49.897 C3.099,50.739 2.538,51.231 1.694,51.231 C0.781,51.231 0.008,50.529 0.008,49.685 C0.009,49.404 0.08,48.983 0.291,48.562 L0.291,48.562 Z M36.673,33.882 L23.749,5.437 L10.755,33.882 L36.673,33.882 L36.673,33.882 Z' />
|
||||
</g>
|
||||
<g>
|
||||
<path d='M40.363,32.075 C40.874,34.44 39.371,36.77 37.006,37.282 C34.641,37.793 32.311,36.29 31.799,33.925 C31.289,31.56 32.791,29.23 35.156,28.718 C37.521,28.207 39.851,29.71 40.363,32.075' fill='currentColor' />
|
||||
<path d='M48.578,28.615 C56.851,45.587 58.558,61.581 52.288,64.778 C45.822,68.076 33.326,56.521 24.375,38.969 C15.424,21.418 13.409,4.518 19.874,1.221 C22.689,-0.216 26.648,1.166 30.959,4.629' stroke='currentColor' stroke-width='3.08' stroke-linecap='round' />
|
||||
<path d='M7.64,39.45 C2.806,36.94 -0.009,33.915 0.154,30.79 C0.531,23.542 16.787,18.497 36.462,19.52 C56.137,20.544 71.781,27.249 71.404,34.497 C71.241,37.622 68.127,40.338 63.06,42.333' stroke='currentColor' stroke-width='3.08' stroke-linecap='round' />
|
||||
<path d='M28.828,59.354 C23.545,63.168 18.843,64.561 15.902,62.653 C9.814,58.702 13.572,42.102 24.296,25.575 C35.02,9.048 48.649,-1.149 54.736,2.803 C57.566,4.639 58.269,9.208 57.133,15.232' stroke='currentColor' stroke-width='3.08' stroke-linecap='round' />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<h1 className='welcome-title'>
|
||||
A hackable text editor for the 21<sup>st</sup> Century
|
||||
</h1>
|
||||
</a>
|
||||
</header>
|
||||
|
||||
<section className='welcome-panel'>
|
||||
<p>For help, please visit</p>
|
||||
<ul>
|
||||
<li>The <a href='https://www.atom.io/docs' dataset={{event: 'atom-docs'}}>Atom docs</a> for Guides and the API reference.</li>
|
||||
<li>The Atom forum at <a href='http://discuss.atom.io' dataset={{event: 'discuss'}}>discuss.atom.io</a></li>
|
||||
<li>The <a href='https://github.com/atom' dataset={{event: 'atom-org'}}>Atom org</a>. This is where all GitHub-created Atom packages can be found.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section className='welcome-panel'>
|
||||
<label>
|
||||
<input className='input-checkbox' type='checkbox' checked={atom.config.get('welcome.showOnStartup')} onchange={this.didChangeShowOnStartup} />
|
||||
Show Welcome Guide when opening Atom
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<footer className='welcome-footer'>
|
||||
<a href='https://atom.io/' dataset={{event: 'footer-atom-io'}}>atom.io</a> <span className='text-subtle'>×</span> <a className='icon icon-octoface' href='https://github.com/' dataset={{event: 'footer-octocat'}} />
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
getURI () {
|
||||
return this.props.uri
|
||||
}
|
||||
|
||||
getTitle () {
|
||||
return 'Welcome'
|
||||
}
|
||||
|
||||
isEqual (other) {
|
||||
other instanceof WelcomeView
|
||||
}
|
||||
}
|
6
packages/welcome/menus/welcome.cson
Normal file
6
packages/welcome/menus/welcome.cson
Normal file
@ -0,0 +1,6 @@
|
||||
'menu': [
|
||||
'label': 'Help'
|
||||
'submenu': [
|
||||
{'label': 'Welcome Guide', 'command': 'welcome:show'}
|
||||
]
|
||||
]
|
2170
packages/welcome/package-lock.json
generated
Normal file
2170
packages/welcome/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
47
packages/welcome/package.json
Normal file
47
packages/welcome/package.json
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "welcome",
|
||||
"version": "0.36.9",
|
||||
"description": "Welcome users to Atom with useful information",
|
||||
"main": "./lib/main",
|
||||
"atomTestRunner": "atom-mocha-test-runner",
|
||||
"repository": "https://github.com/atom/atom",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"atom": ">0.50.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "standard",
|
||||
"test": "atom --test test/*.test.js"
|
||||
},
|
||||
"consumedServices": {
|
||||
"metrics-reporter": {
|
||||
"versions": {
|
||||
"^1.1.0": "consumeReporter"
|
||||
}
|
||||
}
|
||||
},
|
||||
"configSchema": {
|
||||
"showOnStartup": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Show welcome panes with useful information when opening a new Atom window."
|
||||
}
|
||||
},
|
||||
"deserializers": {
|
||||
"WelcomeView": "createWelcomeView",
|
||||
"GuideView": "createGuideView",
|
||||
"ConsentView": "createConsentView"
|
||||
},
|
||||
"dependencies": {
|
||||
"etch": "0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"atom-mocha-test-runner": "^1.0.0",
|
||||
"standard": "^8.6.0"
|
||||
},
|
||||
"standard": {
|
||||
"globals": [
|
||||
"atom"
|
||||
]
|
||||
}
|
||||
}
|
196
packages/welcome/styles/welcome.less
Normal file
196
packages/welcome/styles/welcome.less
Normal file
@ -0,0 +1,196 @@
|
||||
@import "octicon-mixins";
|
||||
@import "ui-variables";
|
||||
|
||||
.welcome {
|
||||
display: flex;
|
||||
font-size: 1.25em;
|
||||
line-height: 1.4;
|
||||
color: @text-color;
|
||||
background-color: @base-background-color;
|
||||
overflow-x: auto;
|
||||
|
||||
// Overrides ----------------------
|
||||
|
||||
p {
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
a {
|
||||
color: @text-color-info;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-top: 1em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.input-checkbox {
|
||||
margin-top: -.2em;
|
||||
margin-right: .5em;
|
||||
}
|
||||
|
||||
// Components ----------------------
|
||||
|
||||
&-container {
|
||||
width: 100%;
|
||||
max-width: 580px;
|
||||
min-width: 300px;
|
||||
margin: auto;
|
||||
padding: 3em 2em;
|
||||
}
|
||||
|
||||
&-header {
|
||||
margin: 0 0 3em 0;
|
||||
}
|
||||
|
||||
&-logo {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 280px;
|
||||
margin: 0 auto 2em auto;
|
||||
color: @text-color-highlight;
|
||||
}
|
||||
|
||||
&-title {
|
||||
font-size: 1.4em;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
&-panel {
|
||||
}
|
||||
|
||||
&-card {
|
||||
margin: 1em 0;
|
||||
|
||||
border-radius: @component-border-radius*2;
|
||||
border: 1px solid @base-border-color;
|
||||
background-color: lighten(@base-background-color, 3%);
|
||||
}
|
||||
|
||||
&-summary {
|
||||
padding: 1em 1.5em;
|
||||
font-size: 1.1em;
|
||||
font-weight: 300;
|
||||
line-height: 1.4;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: lighten(@text-color, 4%);
|
||||
}
|
||||
&::-webkit-details-marker {
|
||||
display: none
|
||||
}
|
||||
&:before {
|
||||
width: 20px;
|
||||
color: @text-color-subtle;
|
||||
details[open] & {
|
||||
color: @text-color-highlight;
|
||||
}
|
||||
}
|
||||
details[open] & {
|
||||
color: @text-color-highlight;
|
||||
}
|
||||
}
|
||||
|
||||
&-highlight {
|
||||
color: @text-color-highlight;
|
||||
}
|
||||
|
||||
&-detail {
|
||||
border-top: 1px solid @base-border-color;
|
||||
padding: 1.5em;
|
||||
.welcome-note {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.btn {
|
||||
margin-top: @component-padding/3;
|
||||
margin-bottom: @component-padding/3;
|
||||
}
|
||||
}
|
||||
|
||||
&-img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
border-radius: 3px;
|
||||
margin: 0 0 1em 0;
|
||||
border: 1px solid @base-border-color;
|
||||
}
|
||||
|
||||
&-consent {
|
||||
margin-top: 3em;
|
||||
|
||||
&-choices {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin: 1em -1em;
|
||||
|
||||
button {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
div {
|
||||
margin: .5em 1em;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.welcome-note {
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-key {
|
||||
display: inline-block;
|
||||
padding: .3em .4em;
|
||||
font-size: .8em;
|
||||
line-height: 1;
|
||||
border-radius: 3px;
|
||||
color: @text-color-highlight;
|
||||
border: 1px solid @text-color-subtle;
|
||||
background: hsla(0,0%,0%,.1);
|
||||
}
|
||||
|
||||
&-love {
|
||||
color: @text-color-subtle;
|
||||
a { color: @text-color-subtle; }
|
||||
|
||||
.icon::before {
|
||||
// Make these octicons look good inlined with text
|
||||
position: relative;
|
||||
top: 4px;
|
||||
width: auto;
|
||||
margin-right: 0;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.icon-logo-github::before {
|
||||
top: 2px;
|
||||
font-size: 3.6em;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
&-note {
|
||||
font-size: .86em;
|
||||
color: @text-color-subtle;
|
||||
|
||||
.icon {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.icon::before {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-footer {
|
||||
margin-top: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
9
packages/welcome/test/helpers.js
Normal file
9
packages/welcome/test/helpers.js
Normal file
@ -0,0 +1,9 @@
|
||||
/** @babel */
|
||||
|
||||
export function conditionPromise (predicate) {
|
||||
return new Promise((resolve) => {
|
||||
setInterval(() => {
|
||||
if (predicate()) resolve()
|
||||
}, 100)
|
||||
})
|
||||
}
|
154
packages/welcome/test/welcome.test.js
Normal file
154
packages/welcome/test/welcome.test.js
Normal file
@ -0,0 +1,154 @@
|
||||
/** @babel */
|
||||
/* global beforeEach, afterEach, describe, it */
|
||||
|
||||
import WelcomePackage from '../lib/welcome-package'
|
||||
import assert from 'assert'
|
||||
import {conditionPromise} from './helpers'
|
||||
|
||||
describe('Welcome', () => {
|
||||
let welcomePackage
|
||||
|
||||
beforeEach(() => {
|
||||
welcomePackage = new WelcomePackage()
|
||||
atom.config.set('welcome.showOnStartup', true)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
atom.reset()
|
||||
})
|
||||
|
||||
describe("when `core.telemetryConsent` is 'undecided'", () => {
|
||||
beforeEach(async () => {
|
||||
atom.config.set('core.telemetryConsent', 'undecided')
|
||||
await welcomePackage.activate()
|
||||
})
|
||||
|
||||
it('opens the telemetry consent pane and the welcome panes', () => {
|
||||
const panes = atom.workspace.getCenter().getPanes()
|
||||
assert.equal(panes.length, 2)
|
||||
assert.equal(panes[0].getItems()[0].getTitle(), 'Telemetry Consent')
|
||||
assert.equal(panes[0].getItems()[1].getTitle(), 'Welcome')
|
||||
assert.equal(panes[1].getItems()[0].getTitle(), 'Welcome Guide')
|
||||
})
|
||||
})
|
||||
|
||||
describe('when `core.telemetryConsent` is not `undecided`', () => {
|
||||
beforeEach(async () => {
|
||||
atom.config.set('core.telemetryConsent', 'no')
|
||||
await welcomePackage.activate()
|
||||
})
|
||||
|
||||
describe('when activated for the first time', () =>
|
||||
it('shows the welcome panes', () => {
|
||||
const panes = atom.workspace.getCenter().getPanes()
|
||||
assert.equal(panes.length, 2)
|
||||
assert.equal(panes[0].getItems()[0].getTitle(), 'Welcome')
|
||||
assert.equal(panes[1].getItems()[0].getTitle(), 'Welcome Guide')
|
||||
})
|
||||
)
|
||||
|
||||
describe('the welcome:show command', () => {
|
||||
it('shows the welcome buffer', async () => {
|
||||
atom.workspace.getCenter().getPanes().map(pane => pane.destroy())
|
||||
assert(!atom.workspace.getActivePaneItem())
|
||||
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
atom.commands.dispatch(workspaceElement, 'welcome:show')
|
||||
|
||||
await conditionPromise(() => atom.workspace.getActivePaneItem())
|
||||
|
||||
const panes = atom.workspace.getCenter().getPanes()
|
||||
assert.equal(panes.length, 2)
|
||||
assert.equal(panes[0].getItems()[0].getTitle(), 'Welcome')
|
||||
})
|
||||
})
|
||||
|
||||
describe('deserializing the pane items', () => {
|
||||
describe('when GuideView is deserialized', () => {
|
||||
it('remembers open sections', () => {
|
||||
const panes = atom.workspace.getCenter().getPanes()
|
||||
const guideView = panes[1].getItems()[0]
|
||||
|
||||
guideView.element.querySelector('details[data-section="snippets"]').setAttribute('open', 'open')
|
||||
guideView.element.querySelector('details[data-section="init-script"]').setAttribute('open', 'open')
|
||||
|
||||
const state = guideView.serialize()
|
||||
|
||||
assert.deepEqual(state.openSections, ['init-script', 'snippets'])
|
||||
|
||||
const newGuideView = welcomePackage.createGuideView(state)
|
||||
assert(!newGuideView.element.querySelector('details[data-section="packages"]').hasAttribute('open'))
|
||||
assert(newGuideView.element.querySelector('details[data-section="snippets"]').hasAttribute('open'))
|
||||
assert(newGuideView.element.querySelector('details[data-section="init-script"]').hasAttribute('open'))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('reporting events', () => {
|
||||
let panes, guideView, reportedEvents
|
||||
beforeEach(() => {
|
||||
panes = atom.workspace.getCenter().getPanes()
|
||||
guideView = panes[1].getItems()[0]
|
||||
reportedEvents = []
|
||||
|
||||
welcomePackage.reporterProxy.sendEvent = (...event) => { reportedEvents.push(event) }
|
||||
})
|
||||
|
||||
describe('GuideView events', () => {
|
||||
it('captures expand and collapse events', () => {
|
||||
guideView.element.querySelector('details[data-section="packages"] summary').click()
|
||||
assert.deepEqual(reportedEvents, [['expand-packages-section']])
|
||||
|
||||
guideView.element.querySelector('details[data-section="packages"]').setAttribute('open', 'open')
|
||||
guideView.element.querySelector('details[data-section="packages"] summary').click()
|
||||
assert.deepEqual(reportedEvents, [['expand-packages-section'], ['collapse-packages-section']])
|
||||
})
|
||||
|
||||
it('captures button events', () => {
|
||||
for (const detailElement of Array.from(guideView.element.querySelector('details'))) {
|
||||
reportedEvents.length = 0
|
||||
|
||||
const sectionName = detailElement.dataset.section
|
||||
const eventName = `clicked-${sectionName}-cta`
|
||||
const primaryButton = detailElement.querySelector('.btn-primary')
|
||||
if (primaryButton) {
|
||||
primaryButton.click()
|
||||
assert.deepEqual(reportedEvents, [[eventName]])
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the reporter changes', () =>
|
||||
it('sends all queued events', () => {
|
||||
welcomePackage.reporterProxy.queue.length = 0
|
||||
|
||||
const reporter1 = {
|
||||
addCustomEvent (category, event) {
|
||||
this.reportedEvents.push({ category, ...event })
|
||||
},
|
||||
reportedEvents: []
|
||||
}
|
||||
const reporter2 = {
|
||||
addCustomEvent (category, event) {
|
||||
this.reportedEvents.push({ category, ...event })
|
||||
},
|
||||
reportedEvents: []
|
||||
}
|
||||
|
||||
welcomePackage.reporterProxy.sendEvent('foo', 'bar', 10)
|
||||
welcomePackage.reporterProxy.sendEvent('foo2', 'bar2', 60)
|
||||
welcomePackage.reporterProxy.setReporter(reporter1)
|
||||
|
||||
assert.deepEqual(reporter1.reportedEvents, [
|
||||
{category: 'welcome-v1', ea: 'foo', el: 'bar', ev: 10},
|
||||
{category: 'welcome-v1', ea: 'foo2', el: 'bar2', ev: 60}
|
||||
])
|
||||
|
||||
welcomePackage.consumeReporter(reporter2)
|
||||
assert.deepEqual(reporter2.reportedEvents, [])
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user