diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..5878c72c87 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[{js/modules/**/*.js, test/modules/**/*.js}] +indent_size = 2 diff --git a/.eslintignore b/.eslintignore index 9569b6efc8..c4a7080040 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,17 +1,23 @@ build/** components/** +coverage/** dist/** libtextsecure/** -coverage/** # these aren't ready yet, pulling files in one-by-one -js/** -test/** +js/*.js +js/models/**/*.js +js/react/**/*.js +js/views/**/*.js +test/*.js +test/models/*.js +test/views/*.js /*.js + +# ES2015+ files +!js/background.js +!js/models/conversations.js +!js/views/file_input_view.js +!js/views/attachment_view.js !main.js !prepare_build.js - -# all of these files will be new -!test/server/**/*.js - -# all of app/ is included diff --git a/.eslintrc.js b/.eslintrc.js index f4db62c1e5..124289e01e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -11,6 +11,10 @@ module.exports = { 'airbnb-base', ], + plugins: [ + 'more', + ], + rules: { 'comma-dangle': ['error', { arrays: 'always-multiline', @@ -21,7 +25,7 @@ module.exports = { }], // putting params on their own line helps stay within line length limit - 'function-paren-newline': ['error', 'consistent'], + 'function-paren-newline': ['error', 'multiline'], // 90 characters allows three+ side-by-side screens on a standard-size monitor 'max-len': ['error', { @@ -29,6 +33,9 @@ module.exports = { ignoreUrls: true, }], + // encourage consistent use of `async` / `await` instead of `then` + 'more/no-then': 'error', + // it helps readability to put public API at top, 'no-use-before-define': 'off', @@ -37,5 +44,8 @@ module.exports = { // though we have a logger, we still remap console to log to disk 'no-console': 'off', + + // consistently place operators at end of line except ternaries + 'operator-linebreak': 'error', } }; diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index f7228df2e4..a471eff112 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -59,7 +59,7 @@ Operating System: Linked device version: - + ### Link to debug log diff --git a/.travis.yml b/.travis.yml index d2cb9a7aac..2915dcc3bb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ install: - yarn install script: - yarn run generate - - yarn prepare-build + - yarn prepare-beta-build - yarn eslint - yarn test-server - yarn lint diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3289ae3a09..d866823dfb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,7 +12,7 @@ for it or creating a new one yourself. You can use also that issue as a place to your intentions and get feedback from the users most likely to appreciate your changes. You're most likely to have your pull request accepted easily if it addresses bugs already -in the [Next Steps project](https://github.com/WhisperSystems/Signal-Desktop/projects/1), +in the [Next Steps project](https://github.com/signalapp/Signal-Desktop/projects/1), especially if they are near the top of the Backlog column. Those are what we'll be looking at next, so it would be a great help if you helped us out! @@ -24,7 +24,7 @@ ounce of prevention, as they say!](https://www.goodreads.com/quotes/247269-an-ou ## Developer Setup First, you'll need [Node.js](https://nodejs.org/) which matches our current version. -You can check [`.nvmrc` in the `development` branch](https://github.com/WhisperSystems/Signal-Desktop/blob/development/.nvmrc) to see what the current version is. If you have [nvm](https://github.com/creationix/nvm) +You can check [`.nvmrc` in the `development` branch](https://github.com/signalapp/Signal-Desktop/blob/development/.nvmrc) to see what the current version is. If you have [nvm](https://github.com/creationix/nvm) you can just run `nvm use` in the project directory and it will switch to the project's desired Node.js version. [nvm for windows](https://github.com/coreybutler/nvm-windows) is still useful, but it doesn't support `.nvmrc` files. @@ -46,7 +46,7 @@ favorite package manager. Python 2.x and GCC are two key necessary components. Now, run these commands in your preferred terminal in a good directory for development: ``` -git clone https://github.com/WhisperSystems/Signal-Desktop.git +git clone https://github.com/signalapp/Signal-Desktop.git cd Signal-Desktop npm install -g yarn # (only if you don't already have yarn) npm install -g grunt-cli # (only if you don't already have grunt) @@ -215,13 +215,13 @@ and register it with one of your extra phone numbers: First, build Signal for Android or iOS from source, and point its TextSecure service URL to `textsecure-service-staging.whispersystems.org`: -**on Android:** Replace the `SIGNAL_URL` value in [build.gradle](https://github.com/WhisperSystems/Signal-Android/blob/master/build.gradle) +**on Android:** Replace the `SIGNAL_URL` value in [build.gradle](https://github.com/signalapp/Signal-Android/blob/master/build.gradle) **on iOS:** Replace the `textSecureServerURL` value in `TSConstants.h`(located in the SignalServiceKit pod) This task is 1% search and replace, 99% setting up your build environment. Instructions are available for both -the [Android](https://github.com/WhisperSystems/Signal-Android/blob/master/BUILDING.md) -and [iOS](https://github.com/WhisperSystems/Signal-iOS/blob/master/BUILDING.md) projects. +the [Android](https://github.com/signalapp/Signal-Android/blob/master/BUILDING.md) +and [iOS](https://github.com/signalapp/Signal-iOS/blob/master/BUILDING.md) projects. Then you can set up your development build of Signal Desktop as normal. If you've already set up as a standalone install, you can switch by opening the DevTools (View -> Toggle diff --git a/Gruntfile.js b/Gruntfile.js index 2b3181c35d..8eb6f81d77 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -103,6 +103,7 @@ module.exports = function(grunt) { '!js/Mp3LameEncoder.min.js', '!js/libsignal-protocol-worker.js', '!js/components.js', + '!js/modules/**/*.js', '!js/signal_protocol_store.js', '_locales/**/*' ], @@ -174,8 +175,10 @@ module.exports = function(grunt) { '!js/Mp3LameEncoder.min.js', '!js/libsignal-protocol-worker.js', '!js/components.js', + '!js/modules/**/*.js', 'test/**/*.js', '!test/blanket_mocha.js', + '!test/modules/**/*.js', '!test/test.js', ] } @@ -282,7 +285,7 @@ module.exports = function(grunt) { var https = require('https'); var urlBase = "https://s3-us-west-1.amazonaws.com/signal-desktop-builds"; - var keyBase = 'WhisperSystems/Signal-Desktop'; + var keyBase = 'signalapp/Signal-Desktop'; var sha = gitinfo.local.branch.current.SHA; var files = [{ zip: packageJson.name + '-' + packageJson.version + '.zip', diff --git a/README.md b/README.md index faf16c093e..9a74be0d3c 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -[![Build Status](https://travis-ci.org/WhisperSystems/Signal-Desktop.svg?branch=master)](https://travis-ci.org/WhisperSystems/Signal-Desktop) +[![Build Status](https://travis-ci.org/signalapp/Signal-Desktop.svg?branch=master)](https://travis-ci.org/signalapp/Signal-Desktop) Signal Desktop ========================== Signal Desktop is an Electron application that links with your -[Signal Android](https://github.com/WhisperSystems/Signal-Android) - or [Signal iOS](https://github.com/WhisperSystems/Signal-iOS) app. +[Signal Android](https://github.com/signalapp/Signal-Android) + or [Signal iOS](https://github.com/signalapp/Signal-iOS) app. ## Install production version: https://signal.org/download/ @@ -27,7 +27,7 @@ The discussion groups are another good place for questions: https://whispersyste Please search the existing issues for your bug and create a new one if the issue is not yet tracked! -https://github.com/WhisperSystems/Signal-Desktop/issues +https://github.com/signalapp/Signal-Desktop/issues ## Contributing Translations @@ -38,7 +38,7 @@ https://www.transifex.com/projects/p/signal-desktop ## Contributing Code -Please see [CONTRIBUTING.md](https://github.com/WhisperSystems/Signal-Desktop/blob/master/CONTRIBUTING.md) +Please see [CONTRIBUTING.md](https://github.com/signalapp/Signal-Desktop/blob/master/CONTRIBUTING.md) for setup instructions and contributor guidelines. And don't forget to sign the [CLA](https://signal.org/cla/). diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 4f4564b4c3..814fff7be5 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -19,79 +19,65 @@ "message": "&Help", "description": "The label that is used for the Help menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt- combination." }, + "menuSetupWithImport": { + "message": "Set up with import", + "description": "When the application is not yet set up, menu option to start up the import sequence" + }, + "menuSetupAsNewDevice": { + "message": "Set up as new device", + "description": "When the application is not yet set up, menu option to start up the set up as fresh device" + }, + "menuSetupAsStandalone": { + "message": "Set up as standalone device", + "description": "Only available on development modes, menu option to open up the standalone device setup sequence" + }, "loading": { "message": "Loading...", "description": "Message shown on the loading screen before we've loaded any messages" }, - "exportInstructions": { - "message": "The first step is to choose a directory to store this application's exported data. It will contain your message history and sensitive cryptographic data, so be sure to save it somewhere private.", - "description": "Description of the export process" - }, "chooseDirectory": { - "message": "Choose directory", - "description": "Button to allow the user to export all data from app as part of migration process" + "message": "Choose folder", + "description": "Button to allow the user to find a folder on disk" }, - "exportButton": { - "message": "Export", - "desription": "Button shown on the choose directory dialog which starts the export process" + "loadDataHeader": { + "message": "Load your data", + "description": "Header shown on the first screen in the data import process" }, - "exportChooserTitle": { - "message": "Choose target directory for data", - "description": "Title of the popup window used to select data storage location" - }, - "exportAgain": { - "message": "Export again", - "description": "If user has already exported once, this button allows user to do it again if needed" - }, - "exportError": { - "message": "Unfortunately, something went wrong during the export. First, double-check your target empty directory for write access and enough space. Then, please submit a debug log so we can help you get migrated!", - "description": "Helper text if the user went forward on migrating the app, but ran into an error" - }, - "exporting": { - "message": "Please wait while we export your data. It may take several minutes. You can still use Signal on your phone and other devices during this time.", - "description": "Message shown on the migration screen while we export data" - }, - "exportComplete": { - "message": "Your data has been exported to:

$location$

You'll be able to import this data as you set up the new Signal Desktop.", - "description": "Message shown on the migration screen when we are done exporting data", - "placeholders": { - "location": { - "content": "$1", - "example": "/Users/someone/somewhere" - } - } - }, - "installNewSignal": { - "message": "Install new Signal Desktop", - "description": "When export is complete, a button shows which sends user to Signal Desktop install instructions" - }, - "importButton": { - "message": "Import", - "desription": "Button shown on the choose directory dialog which starts the import process" + "loadDataDescription": { + "message": "You've just gone through the export process, and your contacts and messages are waiting patiently on your computer. Select the folder that contains your saved Signal data.", + "description": "Introduction to the process of importing messages and contacts from disk" }, "importChooserTitle": { "message": "Choose directory with exported data", "description": "Title of the popup window used to select data previously exported" }, + "importErrorHeader": { + "message": "Something went wrong!", + "description": "Header of the error screen after a failed import" + }, + "importingHeader": { + "message": "Loading contacts and messages", + "description": "Header of screen shown as data is import" + }, "importError": { - "message": "Unfortunately, something went wrong during the import.

First, double-check your target directory. It should start with 'Signal Export.'

Next, try with a new export of your data from the Chrome App.

If that still fails, please submit a debug log so we can help you get migrated!", + "message": "Make sure you have chosen the correct directory that contains your saved Signal data. Its name should begin with 'Signal Export.' You can also save a new copy of your data from the Chrome App.

If these steps don't work for you, please submit a debug log so that we can help you get migrated!

", "description": "Message shown if the import went wrong." }, - "tryAgain": { - "message": "Try again", + "importAgain": { + "message": "Choose folder and try again", "description": "Button shown if the user runs into an error during import, allowing them to start over" }, - "importInstructions": { - "message": "The first step is to tell us where you previously exported your Signal data. It will be a directory whose name starts with 'Signal Export.'

NOTE: You must only import a set of exported data once. Import makes a copy of the exported client, and duplicate clients interfere with each other.", - "description": "Description of the export process" + "importCompleteHeader": { + "message": "Success!", + "description": "Header shown on the screen at the end of a successful import process" }, - "importing": { - "message": "Please wait while we import your data...", - "description": "Shown as we are loading the user's data from disk" + "importCompleteStartButton": { + "message": "Start using Signal Desktop", + "description": "Button shown at end of successful import process, nothing left but a restart" }, - "importComplete": { - "message": "We've successfully loaded your data. The next step is to restart the application!", - "description": "Shown when the import is complete." + "importCompleteLinkButton": { + "message": "Link this device to your phone", + "description": "Button shown at end of successful 'light' import process, so the standard linking process still needs to happen" }, "selectedLocation": { "message": "your selected location", @@ -526,87 +512,46 @@ "message": "Privacy is possible. Signal makes it easy.", "description": "Tagline displayed under 'installWelcome' string on the install page" }, - "installNew": { - "message": "Set up as new install", - "description": "One of two choices presented on the screen shown on first launch" + "linkYourPhone": { + "message": "Link your phone to Signal Desktop", + "description": "Shown on the front page when the application first starst, above the QR code" }, - "installImport": { - "message": "Set up with exported data", - "description": "One of two choices presented on the screen shown on first launch" + "signalSettings": { + "message": "Signal Settings", + "description": "Used in the guidance to help people find the 'link new device' area of their Signal mobile app" }, - "installGetStartedButton": { - "message": "Get started" + "linkedDevices": { + "message": "Linked Devices", + "description": "Used in the guidance to help people find the 'link new device' area of their Signal mobile app" }, - "installSignalLink": { - "message": "First, install Signal on your mobile phone. We'll link your devices and keep your messages in sync.", - "description": "Prompt the user to install Signal on their phone before linking", - "placeholders": { - "a_params": { - "content": "$1", - "example": "href='http://example.com'" - } - } + "plusButton": { + "message": "'+' Button", + "description": "The button used in Signal Android to add a new linked device" }, - "installSignalLinks": { - "message": "First, install Signal on your Android or iPhone.
We'll link your devices and keep your messages in sync.", - "description": "Prompt the user to install Signal on their phone before linking", - "placeholders": { - "play_store": { - "content": "$1", - "example": "href='http://example.com'" - }, - "app_store": { - "content": "$2", - "example": "href='http://example.com'" - } - } + "linkNewDevice": { + "message": "Link New Device", + "description": "The menu option shown in Signal iOS to add a new linked device" }, - "installGotIt": { - "message": "Got it", - "description": "Button for the user to confirm that they have Signal installed." + "deviceName": { + "message": "Device name", + "description": "The label in settings panel shown for the user-provided name for this desktop instance" }, - "installIHaveSignalButton": { - "message": "I have Signal for Android", - "description": "Button for the user to confirm that they have Signal for Android" + "chooseDeviceName": { + "message": "Choose this device's name", + "description": "The header shown on the 'choose device name' screen in the device linking process" }, - "installFollowUs": { - "message": "Follow us for updates about multi-device support for iOS.", - "placeholders": { - "a_params": { - "content": "$1", - "example": "href='http://example.com'" - } - } + "finishLinkingPhone": { + "message": "Finish linking phone", + "description": "The text on the button to finish the linking process, after choosing the device name" }, - "installAndroidInstructions": { - "message": "Open Signal on your phone and navigate to Settings > Linked devices. Tap the button to add a new device, then scan the code above." - }, - "installConnecting": { - "message": "Connecting...", - "description": "Displayed when waiting for the QR Code" + "initialSync": { + "message": "Syncing contacts and groups", + "description": "Shown during initial link while contacts and groups are being pulled from mobile device" }, "installConnectionFailed": { "message": "Failed to connect to server.", "description": "Displayed when we can't connect to the server." }, - "installGeneratingKeys": { - "message": "Generating Keys" - }, - "installSyncingGroupsAndContacts": { - "message": "Syncing groups and contacts" - }, - "installComputerName": { - "message": "This computer's name will be", - "description": "Text displayed before the input where the user can enter the name for this device." - }, - "installLinkingWithNumber": { - "message": "Linking with", - "description": "Text displayed before the phone number that the user is in the process of linking with" - }, - "installFinalButton": { - "message": "Looking good", - "description": "The final button for the install process, after the user has entered a name for their device" - }, "installTooManyDevices": { "message": "Sorry, you have too many devices linked already. Try removing some." }, @@ -748,6 +693,16 @@ } } }, + "timerSetOnSync": { + "message": "Updating timer to $time$.", + "description": "Message displayed when timer is set on initial link of desktop device.", + "placeholders": { + "time": { + "content": "$1", + "example": "10m" + } + } + }, "theyChangedTheTimer": { "message": "$name$ set the timer to $time$.", "description": "Message displayed when someone else changes the message expiration timer in a conversation.", @@ -908,10 +863,10 @@ "message": "There is a new version of Signal available." }, "autoUpdateNewVersionInstructions": { - "message": "Press Restart to apply the updates." + "message": "Press Restart Signal to apply the updates." }, "autoUpdateRestartButtonLabel": { - "message": "Restart" + "message": "Restart Signal" }, "autoUpdateLaterButtonLabel": { "message": "Later" diff --git a/app/auto_update.js b/app/auto_update.js index efcb70e672..9badffb65a 100644 --- a/app/auto_update.js +++ b/app/auto_update.js @@ -42,7 +42,7 @@ function showUpdateDialog(mainWindow, messages) { if (response === RESTART_BUTTON) { // We delay these update calls because they don't seem to work in this // callback - but only if the message box has a parent window. - // Fixes this bug: https://github.com/WhisperSystems/Signal-Desktop/issues/1864 + // Fixes this bug: https://github.com/signalapp/Signal-Desktop/issues/1864 setTimeout(() => { windowState.markShouldQuit(); autoUpdater.quitAndInstall(); diff --git a/app/config.js b/app/config.js index 237b781b4b..d0eff76d76 100644 --- a/app/config.js +++ b/app/config.js @@ -2,8 +2,14 @@ const path = require('path'); const electronIsDev = require('electron-is-dev'); -const defaultEnvironment = electronIsDev ? 'development' : 'production'; -const environment = process.env.NODE_ENV || defaultEnvironment; +let environment; + +// In production mode, NODE_ENV cannot be customized by the user +if (electronIsDev) { + environment = process.env.NODE_ENV || 'development'; +} else { + environment = 'production'; +} // Set environment vars to configure node-config before requiring it process.env.NODE_ENV = environment; diff --git a/app/logging.js b/app/logging.js index bad52467ab..1fa10e0ea8 100644 --- a/app/logging.js +++ b/app/logging.js @@ -1,3 +1,6 @@ +// NOTE: Temporarily allow `then` until we convert the entire file to `async` / `await`: +/* eslint-disable more/no-then */ + const path = require('path'); const fs = require('fs'); @@ -117,8 +120,8 @@ function eliminateOutOfDateFiles(logPath, date) { const file = { path: target, start: isLineAfterDate(start, date), - end: isLineAfterDate(end[end.length - 1], date) - || isLineAfterDate(end[end.length - 2], date), + end: isLineAfterDate(end[end.length - 1], date) || + isLineAfterDate(end[end.length - 2], date), }; if (!file.start && !file.end) { diff --git a/app/menu.js b/app/menu.js index f12c6a35bc..ce3111258f 100644 --- a/app/menu.js +++ b/app/menu.js @@ -6,6 +6,9 @@ function createTemplate(options, messages) { openNewBugForm, openSupportPage, openForums, + setupWithImport, + setupAsNewDevice, + setupAsStandalone, } = options; const template = [{ @@ -123,6 +126,27 @@ function createTemplate(options, messages) { ], }]; + if (options.includeSetup) { + const fileMenu = template[0]; + + // These are in reverse order, since we're prepending them one at a time + if (options.development) { + fileMenu.submenu.unshift({ + label: messages.menuSetupAsStandalone.message, + click: setupAsStandalone, + }); + } + + fileMenu.submenu.unshift({ + label: messages.menuSetupAsNewDevice.message, + click: setupAsNewDevice, + }); + fileMenu.submenu.unshift({ + label: messages.menuSetupWithImport.message, + click: setupWithImport, + }); + } + if (process.platform === 'darwin') { return updateForMac(template, messages, options); } @@ -134,14 +158,46 @@ function updateForMac(template, messages, options) { const { showWindow, showAbout, + setupWithImport, + setupAsNewDevice, + setupAsStandalone, } = options; // Remove About item and separator from Help menu, since it's on the first menu template[4].submenu.pop(); template[4].submenu.pop(); - // Replace File menu + // Remove File menu template.shift(); + + if (options.includeSetup) { + // Add a File menu just for these setup options. Because we're using unshift(), we add + // the file menu first, though it ends up to the right of the Signal Desktop menu. + const fileMenu = { + label: messages.mainMenuFile.message, + submenu: [ + { + label: messages.menuSetupWithImport.message, + click: setupWithImport, + }, + { + label: messages.menuSetupAsNewDevice.message, + click: setupAsNewDevice, + }, + ], + }; + + if (options.development) { + fileMenu.submenu.push({ + label: messages.menuSetupAsStandalone.message, + click: setupAsStandalone, + }); + } + + template.unshift(fileMenu); + } + + // Add the OSX-specific Signal Desktop menu at the far left template.unshift({ submenu: [ { @@ -170,7 +226,8 @@ function updateForMac(template, messages, options) { }); // Add to Edit menu - template[1].submenu.push( + const editIndex = options.includeSetup ? 2 : 1; + template[editIndex].submenu.push( { type: 'separator', }, diff --git a/appveyor.yml b/appveyor.yml index 8f0ffee4ea..f7a95d3a96 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,7 +19,7 @@ build_script: - node build\grunt.js - type package.json | findstr /v certificateSubjectName > temp.json - move temp.json package.json - - yarn prepare-build + - yarn prepare-beta-build - node_modules\.bin\build --em.environment=%SIGNAL_ENV% --publish=never test_script: diff --git a/background.html b/background.html index d094aadde1..10233e918a 100644 --- a/background.html +++ b/background.html @@ -8,7 +8,7 @@ +
+ + + +
+ - -