Move all status/alert dialogs into the Left Pane
This commit is contained in:
parent
101070bf42
commit
18fd44f504
50 changed files with 1298 additions and 607 deletions
|
@ -244,7 +244,7 @@
|
|||
};
|
||||
Whisper.events.trigger('userChanged', user);
|
||||
|
||||
Whisper.Registration.markDone();
|
||||
window.Signal.Util.Registration.markDone();
|
||||
window.log.info('dispatching registration event');
|
||||
Whisper.events.trigger('registration_done');
|
||||
});
|
||||
|
@ -382,7 +382,10 @@
|
|||
|
||||
showStickerPack: async (packId, key) => {
|
||||
// We can get these events even if the user has never linked this instance.
|
||||
if (Whisper.Import.isIncomplete() || !Whisper.Registration.everDone()) {
|
||||
if (
|
||||
Whisper.Import.isIncomplete() ||
|
||||
!window.Signal.Util.Registration.everDone()
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -559,6 +562,15 @@
|
|||
} finally {
|
||||
initializeRedux();
|
||||
start();
|
||||
window.Signal.Services.initializeNetworkObserver(
|
||||
window.reduxActions.network
|
||||
);
|
||||
window.Signal.Services.initializeUpdateListener(
|
||||
window.reduxActions.updates
|
||||
);
|
||||
window.reduxActions.expiration.hydrateExpirationStatus(
|
||||
window.Signal.Util.hasExpired()
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -609,10 +621,22 @@
|
|||
Signal.State.Ducks.emojis.actions,
|
||||
store.dispatch
|
||||
);
|
||||
actions.expiration = Signal.State.bindActionCreators(
|
||||
Signal.State.Ducks.expiration.actions,
|
||||
store.dispatch
|
||||
);
|
||||
actions.items = Signal.State.bindActionCreators(
|
||||
Signal.State.Ducks.items.actions,
|
||||
store.dispatch
|
||||
);
|
||||
actions.network = Signal.State.bindActionCreators(
|
||||
Signal.State.Ducks.network.actions,
|
||||
store.dispatch
|
||||
);
|
||||
actions.updates = Signal.State.bindActionCreators(
|
||||
Signal.State.Ducks.updates.actions,
|
||||
store.dispatch
|
||||
);
|
||||
actions.user = Signal.State.bindActionCreators(
|
||||
Signal.State.Ducks.user.actions,
|
||||
store.dispatch
|
||||
|
@ -1351,7 +1375,7 @@
|
|||
if (Whisper.Import.isIncomplete()) {
|
||||
window.log.info('Import was interrupted, showing import error screen');
|
||||
appView.openImporter();
|
||||
} else if (Whisper.Registration.everDone()) {
|
||||
} else if (window.Signal.Util.Registration.everDone()) {
|
||||
// listeners
|
||||
Whisper.RotateSignedPreKeyListener.init(Whisper.events, newVersion);
|
||||
window.Signal.RefreshSenderCertificate.initialize({
|
||||
|
@ -1377,9 +1401,6 @@
|
|||
Whisper.events.on('unauthorized', () => {
|
||||
appView.inboxView.networkStatusView.update();
|
||||
});
|
||||
Whisper.events.on('reconnectTimer', () => {
|
||||
appView.inboxView.networkStatusView.setSocketReconnectInterval(60000);
|
||||
});
|
||||
Whisper.events.on('contactsync', () => {
|
||||
if (appView.installView) {
|
||||
appView.openInbox();
|
||||
|
@ -1479,7 +1500,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
if (!Whisper.Registration.everDone()) {
|
||||
if (!window.Signal.Util.Registration.everDone()) {
|
||||
return;
|
||||
}
|
||||
if (Whisper.Import.isIncomplete()) {
|
||||
|
@ -2299,7 +2320,7 @@
|
|||
window.log.warn(
|
||||
'Client is no longer authorized; deleting local configuration'
|
||||
);
|
||||
Whisper.Registration.remove();
|
||||
window.Signal.Util.Registration.remove();
|
||||
|
||||
const NUMBER_ID_KEY = 'number_id';
|
||||
const VERSION_KEY = 'version';
|
||||
|
@ -2317,7 +2338,7 @@
|
|||
|
||||
// These two bits of data are important to ensure that the app loads up
|
||||
// the conversation list, instead of showing just the QR code screen.
|
||||
Whisper.Registration.markEverDone();
|
||||
window.Signal.Util.Registration.markEverDone();
|
||||
textsecure.storage.put(NUMBER_ID_KEY, previousNumberId);
|
||||
|
||||
// These two are important to ensure we don't rip through every message
|
||||
|
|
22
js/expire.js
22
js/expire.js
|
@ -1,22 +0,0 @@
|
|||
// eslint-disable-next-line func-names
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
let BUILD_EXPIRATION = 0;
|
||||
try {
|
||||
BUILD_EXPIRATION = parseInt(window.getExpiration(), 10);
|
||||
if (BUILD_EXPIRATION) {
|
||||
window.log.info(
|
||||
'Build expires: ',
|
||||
new Date(BUILD_EXPIRATION).toISOString()
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
window.extension = window.extension || {};
|
||||
|
||||
window.extension.expired = () =>
|
||||
BUILD_EXPIRATION && Date.now() > BUILD_EXPIRATION;
|
||||
})();
|
|
@ -64,12 +64,16 @@ const {
|
|||
const { createStore } = require('../../ts/state/createStore');
|
||||
const conversationsDuck = require('../../ts/state/ducks/conversations');
|
||||
const emojisDuck = require('../../ts/state/ducks/emojis');
|
||||
const expirationDuck = require('../../ts/state/ducks/expiration');
|
||||
const itemsDuck = require('../../ts/state/ducks/items');
|
||||
const networkDuck = require('../../ts/state/ducks/network');
|
||||
const searchDuck = require('../../ts/state/ducks/search');
|
||||
const stickersDuck = require('../../ts/state/ducks/stickers');
|
||||
const updatesDuck = require('../../ts/state/ducks/updates');
|
||||
const userDuck = require('../../ts/state/ducks/user');
|
||||
|
||||
const conversationsSelectors = require('../../ts/state/selectors/conversations');
|
||||
const registrationSelectors = require('../../ts/state/selectors/registration');
|
||||
const searchSelectors = require('../../ts/state/selectors/search');
|
||||
|
||||
// Migrations
|
||||
|
@ -98,6 +102,14 @@ const Initialization = require('./views/initialization');
|
|||
const { IdleDetector } = require('./idle_detector');
|
||||
const MessageDataMigrator = require('./messages_data_migrator');
|
||||
|
||||
// Processes / Services
|
||||
const {
|
||||
initializeNetworkObserver,
|
||||
} = require('../../ts/services/networkObserver');
|
||||
const {
|
||||
initializeUpdateListener,
|
||||
} = require('../../ts/services/updateListener');
|
||||
|
||||
function initializeMigrations({
|
||||
userDataPath,
|
||||
getRegionCode,
|
||||
|
@ -284,19 +296,30 @@ exports.setup = (options = {}) => {
|
|||
createStickerPreviewModal,
|
||||
createTimeline,
|
||||
};
|
||||
|
||||
const Ducks = {
|
||||
conversations: conversationsDuck,
|
||||
emojis: emojisDuck,
|
||||
expiration: expirationDuck,
|
||||
items: itemsDuck,
|
||||
network: networkDuck,
|
||||
updates: updatesDuck,
|
||||
user: userDuck,
|
||||
search: searchDuck,
|
||||
stickers: stickersDuck,
|
||||
};
|
||||
|
||||
const Selectors = {
|
||||
conversations: conversationsSelectors,
|
||||
registration: registrationSelectors,
|
||||
search: searchSelectors,
|
||||
};
|
||||
|
||||
const Services = {
|
||||
initializeNetworkObserver,
|
||||
initializeUpdateListener,
|
||||
};
|
||||
|
||||
const State = {
|
||||
bindActionCreators,
|
||||
createStore,
|
||||
|
@ -344,6 +367,7 @@ exports.setup = (options = {}) => {
|
|||
OS,
|
||||
RefreshSenderCertificate,
|
||||
Settings,
|
||||
Services,
|
||||
State,
|
||||
Stickers,
|
||||
Types,
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/* global storage, Whisper */
|
||||
|
||||
// eslint-disable-next-line func-names
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
Whisper.Registration = {
|
||||
markEverDone() {
|
||||
storage.put('chromiumRegistrationDoneEver', '');
|
||||
},
|
||||
markDone() {
|
||||
this.markEverDone();
|
||||
storage.put('chromiumRegistrationDone', '');
|
||||
},
|
||||
isDone() {
|
||||
return storage.get('chromiumRegistrationDone') === '';
|
||||
},
|
||||
everDone() {
|
||||
return (
|
||||
storage.get('chromiumRegistrationDoneEver') === '' ||
|
||||
storage.get('chromiumRegistrationDone') === ''
|
||||
);
|
||||
},
|
||||
remove() {
|
||||
storage.remove('chromiumRegistrationDone');
|
||||
},
|
||||
};
|
||||
})();
|
|
@ -83,7 +83,7 @@
|
|||
}
|
||||
|
||||
events.on('timetravel', () => {
|
||||
if (Whisper.Registration.isDone()) {
|
||||
if (window.Signal.Util.Registration.isDone()) {
|
||||
setTimeoutForNextRun();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
});
|
||||
},
|
||||
events: {
|
||||
'click .openInstaller': 'openInstaller', // NetworkStatusView has this button
|
||||
openInbox: 'openInbox',
|
||||
},
|
||||
applyTheme() {
|
||||
|
|
|
@ -2642,7 +2642,7 @@
|
|||
this.model.clearTypingTimers();
|
||||
|
||||
let ToastView;
|
||||
if (extension.expired()) {
|
||||
if (window.reduxStore.getState().expiration.hasExpired) {
|
||||
ToastView = Whisper.ExpiredToast;
|
||||
}
|
||||
if (this.model.isPrivate() && storage.isBlocked(this.model.id)) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
/* global
|
||||
ConversationController,
|
||||
extension,
|
||||
getInboxCollection,
|
||||
i18n,
|
||||
Whisper,
|
||||
Signal
|
||||
|
@ -95,25 +93,6 @@
|
|||
this.setupLeftPane();
|
||||
}
|
||||
|
||||
const inboxCollection = getInboxCollection();
|
||||
|
||||
this.listenTo(inboxCollection, 'messageError', () => {
|
||||
if (this.networkStatusView) {
|
||||
this.networkStatusView.update();
|
||||
}
|
||||
});
|
||||
|
||||
this.networkStatusView = new Whisper.NetworkStatusView();
|
||||
this.$el
|
||||
.find('.network-status-container')
|
||||
.append(this.networkStatusView.render().el);
|
||||
|
||||
if (extension.expired()) {
|
||||
const banner = new Whisper.ExpiredAlertBanner().render();
|
||||
banner.$el.prependTo(this.$el);
|
||||
this.$el.addClass('expired');
|
||||
}
|
||||
|
||||
Whisper.events.on('pack-install-failed', () => {
|
||||
const toast = new Whisper.StickerPackInstallFailedToast();
|
||||
toast.$el.appendTo(this.$el);
|
||||
|
@ -225,15 +204,4 @@
|
|||
this.closeRecording(e);
|
||||
},
|
||||
});
|
||||
|
||||
Whisper.ExpiredAlertBanner = Whisper.View.extend({
|
||||
templateName: 'expired_alert',
|
||||
className: 'expiredAlert clearfix',
|
||||
render_attributes() {
|
||||
return {
|
||||
expiredWarning: i18n('expiredWarning'),
|
||||
upgrade: i18n('upgrade'),
|
||||
};
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
// Keep data around if it's a re-link, or the middle of a light import
|
||||
this.shouldRetainData =
|
||||
Whisper.Registration.everDone() || options.hasExistingData;
|
||||
window.Signal.Util.Registration.everDone() || options.hasExistingData;
|
||||
},
|
||||
render_attributes() {
|
||||
let errorMessage;
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
/* global Whisper, extension, Backbone, moment, i18n */
|
||||
|
||||
// eslint-disable-next-line func-names
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
window.Whisper = window.Whisper || {};
|
||||
|
||||
Whisper.NetworkStatusView = Whisper.View.extend({
|
||||
className: 'network-status',
|
||||
templateName: 'networkStatus',
|
||||
initialize() {
|
||||
this.$el.hide();
|
||||
|
||||
this.renderIntervalHandle = setInterval(this.update.bind(this), 5000);
|
||||
extension.windows.onClosed(() => {
|
||||
clearInterval(this.renderIntervalHandle);
|
||||
});
|
||||
|
||||
setTimeout(this.finishConnectingGracePeriod.bind(this), 5000);
|
||||
|
||||
this.withinConnectingGracePeriod = true;
|
||||
this.setSocketReconnectInterval(null);
|
||||
|
||||
window.addEventListener('online', this.update.bind(this));
|
||||
window.addEventListener('offline', this.update.bind(this));
|
||||
|
||||
this.model = new Backbone.Model();
|
||||
this.listenTo(this.model, 'change', this.onChange);
|
||||
},
|
||||
onReconnectTimer() {
|
||||
this.setSocketReconnectInterval(60000);
|
||||
},
|
||||
finishConnectingGracePeriod() {
|
||||
this.withinConnectingGracePeriod = false;
|
||||
},
|
||||
setSocketReconnectInterval(millis) {
|
||||
this.socketReconnectWaitDuration = moment.duration(millis);
|
||||
},
|
||||
navigatorOnLine() {
|
||||
return navigator.onLine;
|
||||
},
|
||||
getSocketStatus() {
|
||||
return window.getSocketStatus();
|
||||
},
|
||||
getNetworkStatus() {
|
||||
let message = '';
|
||||
let instructions = '';
|
||||
let hasInterruption = false;
|
||||
let action = null;
|
||||
let buttonClass = null;
|
||||
|
||||
const socketStatus = this.getSocketStatus();
|
||||
switch (socketStatus) {
|
||||
case WebSocket.CONNECTING:
|
||||
message = i18n('connecting');
|
||||
this.setSocketReconnectInterval(null);
|
||||
break;
|
||||
case WebSocket.OPEN:
|
||||
this.setSocketReconnectInterval(null);
|
||||
break;
|
||||
case WebSocket.CLOSED:
|
||||
message = i18n('disconnected');
|
||||
instructions = i18n('checkNetworkConnection');
|
||||
hasInterruption = true;
|
||||
break;
|
||||
case WebSocket.CLOSING:
|
||||
default:
|
||||
message = i18n('disconnected');
|
||||
instructions = i18n('checkNetworkConnection');
|
||||
hasInterruption = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
socketStatus === WebSocket.CONNECTING &&
|
||||
!this.withinConnectingGracePeriod
|
||||
) {
|
||||
hasInterruption = true;
|
||||
}
|
||||
if (this.socketReconnectWaitDuration.asSeconds() > 0) {
|
||||
instructions = i18n('attemptingReconnection', [
|
||||
this.socketReconnectWaitDuration.asSeconds(),
|
||||
]);
|
||||
}
|
||||
if (!this.navigatorOnLine()) {
|
||||
hasInterruption = true;
|
||||
message = i18n('offline');
|
||||
instructions = i18n('checkNetworkConnection');
|
||||
} else if (!Whisper.Registration.isDone()) {
|
||||
hasInterruption = true;
|
||||
message = i18n('unlinked');
|
||||
instructions = i18n('unlinkedWarning');
|
||||
action = i18n('relink');
|
||||
buttonClass = 'openInstaller';
|
||||
}
|
||||
|
||||
return {
|
||||
message,
|
||||
instructions,
|
||||
hasInterruption,
|
||||
action,
|
||||
buttonClass,
|
||||
};
|
||||
},
|
||||
update() {
|
||||
const status = this.getNetworkStatus();
|
||||
this.model.set(status);
|
||||
},
|
||||
render_attributes() {
|
||||
return this.model.attributes;
|
||||
},
|
||||
onChange() {
|
||||
this.render();
|
||||
if (this.model.attributes.hasInterruption) {
|
||||
this.$el.slideDown();
|
||||
} else {
|
||||
this.$el.hide();
|
||||
}
|
||||
},
|
||||
});
|
||||
})();
|
Loading…
Add table
Add a link
Reference in a new issue