diff --git a/.gitattributes b/.gitattributes index c49fe81..4e6bb68 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,6 +7,7 @@ # File types which we know are binary # Prefer LF for most file types +*.css text eol=lf *.htm text eol=lf *.html text eol=lf *.js text eol=lf diff --git a/src/main/ScratchDesktopTelemetry.js b/src/main/ScratchDesktopTelemetry.js index ec27205..906a7d4 100644 --- a/src/main/ScratchDesktopTelemetry.js +++ b/src/main/ScratchDesktopTelemetry.js @@ -90,6 +90,11 @@ class ScratchDesktopTelemetry { // make a singleton so it's easy to share across both Electron processes const scratchDesktopTelemetrySingleton = new ScratchDesktopTelemetry(); +// `handle` works with `invoke` +ipcMain.handle('getTelemetryDidOptIn', () => + scratchDesktopTelemetrySingleton.didOptIn +); +// `on` works with `sendSync` (and `send`) ipcMain.on('getTelemetryDidOptIn', event => { event.returnValue = scratchDesktopTelemetrySingleton.didOptIn; }); diff --git a/src/main/index.js b/src/main/index.js index 1688313..8b182ec 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,4 +1,4 @@ -import {BrowserWindow, Menu, app, dialog, ipcMain, systemPreferences} from 'electron'; +import {BrowserWindow, Menu, app, dialog, ipcMain, shell, systemPreferences} from 'electron'; import fs from 'fs-extra'; import path from 'path'; import {URL} from 'url'; @@ -193,8 +193,16 @@ const createWindow = ({search = null, url = 'index.html', ...browserWindowOption } }); + webContents.on('new-window', (event, newWindowUrl) => { + shell.openExternal(newWindowUrl); + event.preventDefault(); + }); + const fullUrl = makeFullUrl(url, search); window.loadURL(fullUrl); + window.once('ready-to-show', () => { + webContents.send('ready-to-show'); + }); return window; }; @@ -210,6 +218,17 @@ const createAboutWindow = () => { return window; }; +const createPrivacyWindow = () => { + const window = createWindow({ + width: _windows.main.width * 0.8, + height: _windows.main.height * 0.8, + parent: _windows.main, + search: 'route=privacy', + title: 'Scratch Desktop Privacy Policy' + }); + return window; +}; + const getIsProjectSave = downloadItem => { switch (downloadItem.getMimeType()) { case 'application/x.scratch.sb3': @@ -371,12 +390,21 @@ app.on('ready', () => { event.preventDefault(); _windows.about.hide(); }); + _windows.privacy = createPrivacyWindow(); + _windows.privacy.on('close', event => { + event.preventDefault(); + _windows.privacy.hide(); + }); }); ipcMain.on('open-about-window', () => { _windows.about.show(); }); +ipcMain.on('open-privacy-policy-window', () => { + _windows.privacy.show(); +}); + // start loading initial project data before the GUI needs it so the load seems faster const initialProjectDataPromise = (async () => { if (argv._.length === 0) { diff --git a/src/renderer/about.css b/src/renderer/about.css new file mode 100644 index 0000000..43f9ce7 --- /dev/null +++ b/src/renderer/about.css @@ -0,0 +1,39 @@ +html, body { + background-color: #4D97FF; + color: white; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: bolder; +} + +a:active, a:hover, a:link, a:visited { + color: currentColor; +} + +a:active, a:hover { + filter: brightness(0.9); +} + +.aboutBox { + margin: 0; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.aboutLogo { + max-width: 10rem; + max-height: 10rem; +} + +.aboutText { + margin: 1.5rem; +} + +.aboutDetails { + font-size: x-small; +} + +.aboutFooter { + font-size: small; +} diff --git a/src/renderer/about.jsx b/src/renderer/about.jsx index 9b121bc..204b829 100644 --- a/src/renderer/about.jsx +++ b/src/renderer/about.jsx @@ -1,45 +1,29 @@ import React from 'react'; -import ReactDOM from 'react-dom'; import {productName, version} from '../../package.json'; import logo from '../icon/ScratchDesktop.svg'; +import styles from './about.css'; -// TODO: localization? const AboutElement = () => ( -
{component} | {componentVersion} |
+ The Scratch Foundation (“Scratch”, “we” or “us”) understands how + important privacy is to our community. We wrote this Privacy Policy to explain what Personal Information + (“Information”) we collect through our offline editor (the “Scratch App”), how we use, process, and share it, and what we're doing to keep it safe. It + also tells you about your rights and choices with respect to your Personal Information, and how you can contact us if you have any questions or concerns. +
++ For the purpose of this Privacy Policy, “Information” means any information relating to an + identified or identifiable individual. The Scratch App automatically collects and stores locally the + following Information through its telemetry system: the title of your project in text form, language + setting, time zone and events related to your use of the Scratch App (namely when the Scratch App was + opened and closed, if a project file has been loaded or saved, or if a new project is created). If you + choose to turn on the telemetry sharing feature, the Scratch App will transmit this information to Scratch. + Projects created in the Scratch App are not transmitted to or accessible by Scratch. +
+We use this Information for the following purposes:
++ If you are located in the European Economic Area, the United Kingdom or Switzerland, we only process your + Information based on a valid legal ground. A “legal ground” is a reason that justifies our use + of your Information. In this case, we or a third party have a legitimate interest in using your Information + (if you choose to allow the Scratch App to send the Scratch team your Information) to create, analyze and + share your aggregated or de-identified Information for research purposes, to analyze and enhance your + learning experience on the Scratch App and otherwise ensure and improve the safety, security, and + performance of the Scratch App. We only rely on our or a third party’s legitimate interests to process your + Information when these interests are not overridden by your rights and interests. +
++ We disclose information that we collect through the Scratch App to third parties in the following + circumstances: +
++ The Scratch Foundation is a 501(c)(3) nonprofit organization. As such, the Children's Online Privacy + Protection Act (COPPA) does not apply to Scratch. Nevertheless, Scratch takes children's privacy + seriously. Scratch collects only minimal information from its users, and only uses and discloses + information to provide the services and for limited other purposes, such as research, as described in this + Privacy Policy. +
++ Scratch does not collect information from a student's education record, as defined by the Family + Educational Rights and Privacy Act (FERPA). Scratch does not disclose information of students to any third + parties except as described in this Privacy Policy. +
++ If you are located in the European Economic Area, the United Kingdom or Switzerland, you have certain + rights in relation to your Information: +
++ In addition to the above-mentioned rights, you also have the right to lodge a complaint with a competent + supervisory authority subject to applicable law. However, there are exceptions and limitations to each of + these rights. We may, for example, refuse to act on a request if the request is manifestly unfounded or + excessive, or if the request is likely to adversely affect the rights and freedoms of others, prejudice the + execution or enforcement of the law, interfere with pending or future litigation, or infringe applicable + law. To submit a request to exercise your rights, please contact help@scratch.mit.edu for assistance. +
++ We take measures to delete your Information or keep it in a form that does not allow you to be identified + when this Information is no longer necessary for the purposes for which we process it, unless we are + required by law to keep this Information for a longer period. When determining the retention period, we + take into account various criteria, such as the type of services requested by or provided to you, the + nature and length of our relationship with you, possible re-enrollment with our services, the impact on the + services we provide to you if we delete some Information from or about you, mandatory retention periods + provided by law and the statute of limitations. +
++ Scratch has in place administrative, physical, and technical procedures that are intended to protect the + Information we collect on the Scratch App against accidental or unlawful destruction, accidental loss, + unauthorized alteration, unauthorized disclosure or access, misuse, and any other unlawful form of + processing of the Information. However, as effective as these measures are, no security system is + impenetrable. We cannot completely guarantee the security of our databases, nor can we guarantee that the + Information you supply will not be intercepted while being transmitted to us over the Internet. +
++ We may transfer your Information to countries other than the country where you are located, including to + the U.S. (where our Scratch servers are located) or any other country in which we or our service providers + maintain facilities. If you are located in the European Economic Area, the United Kingdom or Switzerland, + or other regions with laws governing data collection and use that may differ from U.S. law, please note + that we may transfer your Information to a country and jurisdiction that does not have the same data + protection laws as your jurisdiction. We apply appropriate safeguards to the Information processed and + transferred on our behalf. Please contact us for more information on the safeguards used. +
++ We review our Privacy Policy on a periodic basis, and we may modify our policies as appropriate. We will + notify you of any material changes. We encourage you to review our Privacy Policy on a regular basis. The + “Last Updated” date at the top of this page indicates when this Privacy Policy was last + revised. Your continued use of the Scratch App following these changes means that you accept the revised + Privacy Policy. +
++ The Scratch Foundation is the entity responsible for the processing of your Information. If you have any + questions about this Privacy Policy, or if you would like to exercise your rights to your Information, you + may contact us at help@scratch.mit.edu or via mail at: +
+