diff --git a/background.html b/background.html
index 18e485aef..1c931477a 100644
--- a/background.html
+++ b/background.html
@@ -575,7 +575,6 @@
-
diff --git a/fixtures/ghost-kitty.mp4 b/fixtures/ghost-kitty.mp4
new file mode 100644
index 000000000..936349ea5
Binary files /dev/null and b/fixtures/ghost-kitty.mp4 differ
diff --git a/fixtures/pixabay-Soap-Bubble-7141.mp4 b/fixtures/pixabay-Soap-Bubble-7141.mp4
new file mode 100644
index 000000000..f600bea00
Binary files /dev/null and b/fixtures/pixabay-Soap-Bubble-7141.mp4 differ
diff --git a/js/background.js b/js/background.js
index 737355de4..4aa4e0500 100644
--- a/js/background.js
+++ b/js/background.js
@@ -256,8 +256,7 @@
window.getDefaultFileServer()
);
}
- // are there limits on tracking, is this unneeded?
- // window.mixpanel.track("Desktop boot");
+
window.initialisedAPI = true;
if (storage.get('isSecondaryDevice')) {
diff --git a/js/models/conversations.js b/js/models/conversations.js
index 17278914d..f6f81c0a2 100644
--- a/js/models/conversations.js
+++ b/js/models/conversations.js
@@ -233,6 +233,12 @@
const lastMessageModel = messages.at(0);
if (lastMessageModel) {
lastMessageModel.acceptFriendRequest();
+ await this.markRead();
+ window.Whisper.events.trigger(
+ 'showConversation',
+ this.id,
+ lastMessageModel.id
+ );
}
},
async declineFriendRequest() {
diff --git a/js/modules/loki_app_dot_net_api.js b/js/modules/loki_app_dot_net_api.js
index 0831a4028..2760a0d61 100644
--- a/js/modules/loki_app_dot_net_api.js
+++ b/js/modules/loki_app_dot_net_api.js
@@ -1666,7 +1666,6 @@ class LokiPublicChannelAPI {
objBody: payload,
});
if (!res.err && res.response) {
- window.mixpanel.track('Public Message Sent');
return res.response.data.id;
}
if (res.err) {
@@ -1681,7 +1680,6 @@ class LokiPublicChannelAPI {
}
// there's no retry on desktop
// this is supposed to be after retries
- window.mixpanel.track('Failed to Send Public Message');
return false;
}
}
diff --git a/js/modules/loki_message_api.js b/js/modules/loki_message_api.js
index ca42bb468..b581a16ff 100644
--- a/js/modules/loki_message_api.js
+++ b/js/modules/loki_message_api.js
@@ -133,7 +133,6 @@ class LokiMessageAPI {
try {
// eslint-disable-next-line more/no-then
success = await firstTrue(promises);
- window.mixpanel.track('Sent Message Using Swarm API');
} catch (e) {
if (e instanceof textsecure.WrongDifficultyError) {
// Force nonce recalculation
@@ -147,7 +146,6 @@ class LokiMessageAPI {
throw e;
}
if (!success) {
- window.mixpanel.track('Failed to Send Message Using Swarm API');
throw new window.textsecure.EmptySwarmError(
pubKey,
'Ran out of swarm nodes to query'
@@ -221,7 +219,6 @@ class LokiMessageAPI {
} catch (e) {
log.warn('Loki send message:', e);
if (e instanceof textsecure.WrongSwarmError) {
- window.mixpanel.track('Migrated Snode');
const { newSwarm } = e;
await lokiSnodeAPI.updateSwarmNodes(params.pubKey, newSwarm);
this.sendingData[params.timestamp].swarm = newSwarm;
diff --git a/js/modules/loki_mixpanel.js b/js/modules/loki_mixpanel.js
deleted file mode 100644
index bf9b10e23..000000000
--- a/js/modules/loki_mixpanel.js
+++ /dev/null
@@ -1,12 +0,0 @@
-const Mixpanel = require('mixpanel');
-
-class LokiMixpanelAPI {
- constructor() {
- this.mixpanel = Mixpanel.init('736cd9a854a157591153efacd1164e9a');
- }
- track(label) {
- this.mixpanel.track(label);
- }
-}
-
-module.exports = LokiMixpanelAPI;
diff --git a/js/modules/loki_snode_api.js b/js/modules/loki_snode_api.js
index bb6eb9946..14a536e53 100644
--- a/js/modules/loki_snode_api.js
+++ b/js/modules/loki_snode_api.js
@@ -64,7 +64,6 @@ class LokiSnodeAPI {
}));
} catch (e) {
log.warn('initialiseRandomPool error', JSON.stringify(e));
- window.mixpanel.track('Seed Node Failed');
if (seedNodes.length === 0) {
throw new window.textsecure.SeedNodeError(
'Failed to contact seed node'
@@ -80,7 +79,6 @@ class LokiSnodeAPI {
const filteredNodes = swarmNodes.filter(
node => node.address !== nodeUrl && node.ip !== nodeUrl
);
- window.mixpanel.track('Unreachable Snode');
await conversation.updateSwarmNodes(filteredNodes);
}
diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js
index 64251e1f9..3caf3b520 100644
--- a/js/views/conversation_view.js
+++ b/js/views/conversation_view.js
@@ -350,6 +350,8 @@
props: getGroupSettingsProp(this.model),
});
this.$('.conversation-content-right').append(this.groupSettings.el);
+ } else {
+ this.groupSettings.update(getGroupSettingsProp(this.model));
}
this.$('.conversation-content-right').show();
};
@@ -875,9 +877,7 @@
},
updateScrollDownButton(count) {
- if (this.scrollDownButton) {
- this.scrollDownButton.increment(count);
- } else {
+ if (!this.scrollDownButton) {
this.scrollDownButton = new Whisper.ScrollDownButtonView({ count });
this.scrollDownButton.render();
const container = this.$('.discussion-container');
diff --git a/js/views/inbox_view.js b/js/views/inbox_view.js
index f0a5eab57..515fb19fd 100644
--- a/js/views/inbox_view.js
+++ b/js/views/inbox_view.js
@@ -327,8 +327,6 @@
$target.toggleClass('section-toggle-visible');
},
async openConversation(id, messageId) {
- const conversationExists = await ConversationController.get(id);
-
// If we call this to create a new conversation, it can only be private
// (group conversations are created elsewhere)
const conversation = await ConversationController.getOrCreateAndWait(
@@ -341,19 +339,6 @@
}
if (conversation) {
- if (conversation.isRss()) {
- window.mixpanel.track('RSS Feed Opened');
- }
- if (conversation.isPublic()) {
- window.mixpanel.track('Loki Public Chat Opened');
- }
- if (conversation.isPrivate()) {
- if (conversation.isMe()) {
- window.mixpanel.track('Note To Self Opened');
- } else if (conversationExists) {
- window.mixpanel.track('Conversation Opened');
- }
- }
conversation.updateProfileName();
}
diff --git a/js/views/session_registration_view.js b/js/views/session_registration_view.js
index 41c2b24ee..b1ec89621 100644
--- a/js/views/session_registration_view.js
+++ b/js/views/session_registration_view.js
@@ -120,7 +120,7 @@
window.Session = window.Session || {};
window.Session.setNewSessionID = sessionID => {
- const el = document.querySelector('.session-id-editable');
+ const el = document.querySelector('.session-id-editable-textarea');
const fx = new TextScramble(el);
el.value = sessionID;
fx.setText(sessionID);
diff --git a/libtextsecure/account_manager.js b/libtextsecure/account_manager.js
index 14559d1cd..1dfca9417 100644
--- a/libtextsecure/account_manager.js
+++ b/libtextsecure/account_manager.js
@@ -25,9 +25,6 @@
(function() {
window.textsecure = window.textsecure || {};
- // set up mixpanel
- window.mixpanel = window.mixpanel || new window.LokiMixpanelAPI();
-
const ARCHIVE_AGE = 7 * 24 * 60 * 60 * 1000;
function AccountManager(username, password) {
@@ -142,10 +139,8 @@
).toArrayBuffer();
return libsignal.Curve.async.createKeyPair(privKey);
};
- window.mixpanel.track('Seed Restored');
} else {
generateKeypair = libsignal.KeyHelper.generateIdentityKeyPair;
- window.mixpanel.track('Seed Created');
}
return this.queueTask(() =>
generateKeypair().then(async identityKeyPair =>
diff --git a/main.js b/main.js
index a5f55504a..2eb625db8 100644
--- a/main.js
+++ b/main.js
@@ -14,6 +14,7 @@ const packageJson = require('./package.json');
const GlobalErrors = require('./app/global_errors');
GlobalErrors.addHandler();
+const electronLocalshortcut = require('electron-localshortcut');
const getRealPath = pify(fs.realpath);
const {
@@ -285,6 +286,13 @@ function createWindow() {
// Disable system main menu
mainWindow.setMenu(null);
+ electronLocalshortcut.register(mainWindow, 'f5', () => {
+ mainWindow.reload();
+ });
+ electronLocalshortcut.register(mainWindow, 'CommandOrControl+R', () => {
+ mainWindow.reload();
+ });
+
function captureAndSaveWindowStats() {
if (!mainWindow) {
return;
diff --git a/package.json b/package.json
index 3fb07d135..876e1aee9 100644
--- a/package.json
+++ b/package.json
@@ -41,19 +41,23 @@
"test-node": "mocha --recursive --exit test/app test/modules ts/test libloki/test/node",
"test-node-coverage": "nyc --reporter=lcov --reporter=text mocha --recursive test/app test/modules ts/test libloki/test/node",
"test-node-coverage-html": "nyc --reporter=lcov --reporter=html mocha --recursive test/a/* */pp test/modules ts/test libloki/test/node",
- "eslint": "eslint .",
+ "eslint": "eslint --cache .",
+ "eslint-full": "eslint .",
"lint": "yarn format --list-different && yarn lint-windows",
+ "lint-full": "yarn format-full --list-different; yarn lint-windows-full",
"dev-lint": "yarn format --list-different; yarn lint-windows",
"lint-windows": "yarn eslint && yarn tslint",
+ "lint-windows-full": "yarn eslint-full && yarn tslint",
"lint-deps": "node ts/util/lint/linter.js",
"tslint": "tslint --format stylish --project .",
- "format": "prettier --write \"*.{css,js,json,md,scss,ts,tsx}\" \"./**/*.{css,js,json,md,scss,ts,tsx}\"",
+ "format": "prettier --write `git ls-files --modified *.{css,js,json,md,scss,ts,tsx}` `git ls-files --modified ./**/*.{css,js,json,md,scss,ts,tsx}`",
+ "format-full": "prettier --write \"*.{css,js,json,md,scss,ts,tsx}\" \"./**/*.{css,js,json,md,scss,ts,tsx}\"",
"transpile": "tsc",
"clean-transpile": "rimraf ts/**/*.js && rimraf ts/*.js",
"open-coverage": "open coverage/lcov-report/index.html",
"styleguide": "styleguidist server",
"pow-metrics": "node metrics_app.js localhost 9000",
- "ready": "yarn clean-transpile && yarn grunt && yarn lint && yarn test-node && yarn test-electron && yarn lint-deps"
+ "ready": "yarn clean-transpile && yarn grunt && yarn lint-full && yarn test-node && yarn test-electron && yarn lint-deps"
},
"dependencies": {
"@journeyapps/sqlcipher": "https://github.com/scottnonnenberg-signal/node-sqlcipher.git#2e28733b61640556b0272a3bfc78b0357daf71e6",
@@ -74,6 +78,7 @@
"electron-context-menu": "^0.15.0",
"electron-editor-context-menu": "1.1.1",
"electron-is-dev": "0.3.0",
+ "electron-localshortcut": "^3.2.1",
"emoji-datasource": "4.0.0",
"emoji-datasource-apple": "4.0.0",
"emoji-js": "3.4.0",
@@ -94,7 +99,6 @@
"libsodium-wrappers": "^0.7.4",
"linkify-it": "2.0.3",
"lodash": "4.17.11",
- "mixpanel": "^0.10.2",
"mkdirp": "0.5.1",
"moment": "2.21.0",
"mustache": "2.3.0",
diff --git a/preload.js b/preload.js
index 005b2318b..66a510490 100644
--- a/preload.js
+++ b/preload.js
@@ -371,10 +371,6 @@ window.LokiFileServerAPI = require('./js/modules/loki_file_server_api');
window.LokiRssAPI = require('./js/modules/loki_rss_api');
-const LokiMixpanelAPI = require('./js/modules/loki_mixpanel.js');
-
-window.mixpanel = new LokiMixpanelAPI();
-
window.localServerPort = config.localServerPort;
window.mnemonic = require('./libloki/modules/mnemonic');
diff --git a/stylesheets/_conversation.scss b/stylesheets/_conversation.scss
index 9faf2e72f..d2453c1b2 100644
--- a/stylesheets/_conversation.scss
+++ b/stylesheets/_conversation.scss
@@ -457,10 +457,6 @@
resize: none;
font-size: 1em;
font-family: inherit;
-
- &[disabled='disabled'] {
- background: $color-light-35;
- }
}
.capture-audio {
float: right;
diff --git a/stylesheets/_theme_dark.scss b/stylesheets/_theme_dark.scss
index 52de9723a..837d93bf3 100644
--- a/stylesheets/_theme_dark.scss
+++ b/stylesheets/_theme_dark.scss
@@ -49,7 +49,7 @@ body.dark-theme {
outline: 0;
&[disabled='disabled'] {
- background: $color-light-90;
+ cursor: not-allowed;
}
}
}
diff --git a/test/index.html b/test/index.html
index fd200152f..fb206383b 100644
--- a/test/index.html
+++ b/test/index.html
@@ -550,7 +550,6 @@
-
diff --git a/ts/components/session/LeftPaneContactSection.tsx b/ts/components/session/LeftPaneContactSection.tsx
index ad84635b7..e78c14005 100644
--- a/ts/components/session/LeftPaneContactSection.tsx
+++ b/ts/components/session/LeftPaneContactSection.tsx
@@ -237,7 +237,7 @@ export class LeftPaneContactSection extends React.Component {
}
private handleOnAddContact() {
- const sessionID = this.state.addContactRecipientID;
+ const sessionID = this.state.addContactRecipientID.trim();
const error = validateNumber(sessionID, window.i18n);
if (error) {
diff --git a/ts/components/session/LeftPaneMessageSection.tsx b/ts/components/session/LeftPaneMessageSection.tsx
index d5b3d15ae..581acb8a9 100644
--- a/ts/components/session/LeftPaneMessageSection.tsx
+++ b/ts/components/session/LeftPaneMessageSection.tsx
@@ -355,6 +355,7 @@ export class LeftPaneMessageSection extends React.Component {
}
let pubkey: string;
pubkey = this.state.pubKeyPasted || this.props.searchTerm;
+ pubkey = pubkey.trim();
const error = validateNumber(pubkey);
if (!error) {
diff --git a/ts/components/session/SessionChannelSettings.tsx b/ts/components/session/SessionChannelSettings.tsx
index f7462ceaa..45e65d29a 100644
--- a/ts/components/session/SessionChannelSettings.tsx
+++ b/ts/components/session/SessionChannelSettings.tsx
@@ -49,6 +49,18 @@ export class SessionChannelSettings extends React.Component {
.ignore();
}
+ public componentDidUpdate() {
+ this.getMediaGalleryProps()
+ .then(({ documents, media, onItemClick }) => {
+ this.setState({
+ documents,
+ media,
+ onItemClick,
+ });
+ })
+ .ignore();
+ }
+
public async getMediaGalleryProps() {
// We fetch more documents than media as they don’t require to be loaded
// into memory right away. Revisit this once we have infinite scrolling:
diff --git a/ts/components/session/SessionIdEditable.tsx b/ts/components/session/SessionIdEditable.tsx
index cc5c140d2..a7fd4aa09 100644
--- a/ts/components/session/SessionIdEditable.tsx
+++ b/ts/components/session/SessionIdEditable.tsx
@@ -30,6 +30,7 @@ export class SessionIdEditable extends React.PureComponent {
return (