New media permission, show dialog when not enabled for voice msg
UI now in separate renderer: - the permissions popup - settings dialog - debug log dialog - about window Couple bug fixes: - About Window: Fix 'escape' to close window - Remove outdated dist/copy tasks from Gruntfile Eslintified settings_view.js
This commit is contained in:
parent
9d9a797bda
commit
ad4387803b
33 changed files with 1192 additions and 383 deletions
24
js/about_start.js
Normal file
24
js/about_start.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Add version
|
||||
$('.version').text(`v${window.getVersion()}`);
|
||||
|
||||
// Add debugging metadata - environment if not production, app instance name
|
||||
const states = [];
|
||||
|
||||
if (window.getEnvironment() !== 'production') {
|
||||
states.push(window.getEnvironment());
|
||||
}
|
||||
if (window.getAppInstance()) {
|
||||
states.push(window.getAppInstance());
|
||||
}
|
||||
|
||||
$('.environment').text(states.join(' - '));
|
||||
|
||||
// Install the 'dismiss with escape key' handler
|
||||
$(document).on('keyup', function(e) {
|
||||
if (e.keyCode === 27) {
|
||||
window.closeAbout();
|
||||
}
|
||||
});
|
||||
|
||||
// Localize the privacy string
|
||||
$('.privacy').text(window.i18n('privacyPolicy'));
|
|
@ -123,6 +123,54 @@
|
|||
}
|
||||
first = false;
|
||||
|
||||
// These make key operations available to IPC handlers created in preload.js
|
||||
window.Events = {
|
||||
getDeviceName: () => textsecure.storage.user.getDeviceName(),
|
||||
|
||||
getThemeSetting: () => storage.get('theme-setting'),
|
||||
setThemeSetting: value => {
|
||||
storage.put('theme-setting', value);
|
||||
onChangeTheme();
|
||||
},
|
||||
getHideMenuBar: () => storage.get('hide-menu-bar'),
|
||||
setHideMenuBar: value => {
|
||||
storage.get('hide-menu-bar', value);
|
||||
window.setAutoHideMenuBar(value);
|
||||
window.setMenuBarVisibility(!value);
|
||||
},
|
||||
|
||||
getNotificationSetting: () =>
|
||||
storage.get('notification-setting', 'message'),
|
||||
setNotificationSetting: value =>
|
||||
storage.get('notification-setting', value),
|
||||
getAudioNotification: () => storage.get('audio-notification'),
|
||||
setAudioNotification: value => storage.put('audio-notification', value),
|
||||
|
||||
// eslint-disable-next-line eqeqeq
|
||||
isPrimary: () => textsecure.storage.user.getDeviceId() == '1',
|
||||
getSyncRequest: () =>
|
||||
new Promise((resolve, reject) => {
|
||||
const syncRequest = window.getSyncRequest();
|
||||
syncRequest.addEventListener('success', resolve);
|
||||
syncRequest.addEventListener('timeout', reject);
|
||||
}),
|
||||
getLastSyncTime: () => storage.get('synced_at'),
|
||||
setLastSyncTime: value => storage.put('synced_at', value),
|
||||
|
||||
addDarkOverlay: () => {
|
||||
if ($('.dark-overlay').length) {
|
||||
return;
|
||||
}
|
||||
$(document.body).prepend('<div class="dark-overlay"></div>');
|
||||
$('.dark-overlay').on('click', () => $('.dark-overlay').remove());
|
||||
},
|
||||
removeDarkOverlay: () => $('.dark-overlay').remove(),
|
||||
deleteAllData: () => {
|
||||
const clearDataView = new window.Whisper.ClearDataView().render();
|
||||
$('body').append(clearDataView.el);
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
await ConversationController.load();
|
||||
} finally {
|
||||
|
@ -208,16 +256,6 @@
|
|||
Whisper.events.on('showDebugLog', () => {
|
||||
appView.openDebugLog();
|
||||
});
|
||||
Whisper.events.on('showSettings', () => {
|
||||
if (!appView || !appView.inboxView) {
|
||||
console.log(
|
||||
"background: Event: 'showSettings':" +
|
||||
' Expected `appView.inboxView` to exist.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
appView.inboxView.showSettings();
|
||||
});
|
||||
Whisper.events.on('unauthorized', () => {
|
||||
appView.inboxView.networkStatusView.update();
|
||||
});
|
||||
|
|
13
js/debug_log_start.js
Normal file
13
js/debug_log_start.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
$(document).on('keyup', function(e) {
|
||||
if (e.keyCode === 27) {
|
||||
window.closeDebugLog();
|
||||
}
|
||||
});
|
||||
|
||||
const $body = $(document.body);
|
||||
|
||||
// got.js appears to need this to successfully submit debug logs to the cloud
|
||||
window.setImmediate = window.nodeSetImmediate;
|
||||
|
||||
window.view = new Whisper.DebugLogView();
|
||||
window.view.$el.appendTo($body);
|
|
@ -55,32 +55,23 @@ const Initialization = require('./views/initialization');
|
|||
const { IdleDetector } = require('./idle_detector');
|
||||
const MessageDataMigrator = require('./messages_data_migrator');
|
||||
|
||||
exports.setup = (options = {}) => {
|
||||
const { Attachments, userDataPath, getRegionCode } = options;
|
||||
|
||||
const Components = {
|
||||
ContactDetail,
|
||||
ContactName,
|
||||
ConversationTitle,
|
||||
EmbeddedContact,
|
||||
Emojify,
|
||||
Lightbox,
|
||||
LightboxGallery,
|
||||
MediaGallery,
|
||||
MessageBody,
|
||||
Types: {
|
||||
Message: MediaGalleryMessage,
|
||||
},
|
||||
Quote,
|
||||
};
|
||||
function initializeMigrations({
|
||||
Attachments,
|
||||
userDataPath,
|
||||
Type,
|
||||
getRegionCode,
|
||||
}) {
|
||||
if (!Attachments) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const attachmentsPath = Attachments.getPath(userDataPath);
|
||||
const readAttachmentData = Attachments.createReader(attachmentsPath);
|
||||
const loadAttachmentData = AttachmentType.loadData(readAttachmentData);
|
||||
const loadAttachmentData = Type.loadData(readAttachmentData);
|
||||
|
||||
const Migrations = {
|
||||
return {
|
||||
attachmentsPath,
|
||||
deleteAttachmentData: AttachmentType.deleteData(
|
||||
deleteAttachmentData: Type.deleteData(
|
||||
Attachments.createDeleter(attachmentsPath)
|
||||
),
|
||||
getAbsoluteAttachmentPath: Attachments.createAbsolutePathGetter(
|
||||
|
@ -100,6 +91,33 @@ exports.setup = (options = {}) => {
|
|||
Attachments.createWriterForExisting(attachmentsPath)
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
exports.setup = (options = {}) => {
|
||||
const { Attachments, userDataPath, getRegionCode } = options;
|
||||
|
||||
const Migrations = initializeMigrations({
|
||||
Attachments,
|
||||
userDataPath,
|
||||
Type: AttachmentType,
|
||||
getRegionCode,
|
||||
});
|
||||
|
||||
const Components = {
|
||||
ContactDetail,
|
||||
ContactName,
|
||||
ConversationTitle,
|
||||
EmbeddedContact,
|
||||
Emojify,
|
||||
Lightbox,
|
||||
LightboxGallery,
|
||||
MediaGallery,
|
||||
MessageBody,
|
||||
Types: {
|
||||
Message: MediaGalleryMessage,
|
||||
},
|
||||
Quote,
|
||||
};
|
||||
|
||||
const Types = {
|
||||
Attachment: AttachmentType,
|
||||
|
|
|
@ -134,6 +134,8 @@
|
|||
break;
|
||||
}
|
||||
|
||||
console.log({ title, message, iconUrl });
|
||||
|
||||
const shouldHideExpiringMessageBody =
|
||||
last.isExpiringMessage && Signal.OS.isMacOS();
|
||||
if (shouldHideExpiringMessageBody) {
|
||||
|
|
19
js/permissions_popup_start.js
Normal file
19
js/permissions_popup_start.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
$(document).on('keyup', function(e) {
|
||||
if (e.keyCode === 27) {
|
||||
window.closePermissionsPopup();
|
||||
}
|
||||
});
|
||||
|
||||
const $body = $(document.body);
|
||||
|
||||
window.view = new Whisper.ConfirmationDialogView({
|
||||
message: i18n('audioPermissionNeeded'),
|
||||
okText: i18n('allowAccess'),
|
||||
resolve: () => {
|
||||
window.setMediaPermissions(true);
|
||||
window.closePermissionsPopup();
|
||||
},
|
||||
reject: window.closePermissionsPopup,
|
||||
});
|
||||
|
||||
window.view.$el.appendTo($body);
|
29
js/settings_start.js
Normal file
29
js/settings_start.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
$(document).on('keyup', function(e) {
|
||||
if (e.keyCode === 27) {
|
||||
window.closeSettings();
|
||||
}
|
||||
});
|
||||
|
||||
const $body = $(document.body);
|
||||
|
||||
const getInitialData = async () => ({
|
||||
deviceName: await window.getDeviceName(),
|
||||
|
||||
themeSetting: await window.getThemeSetting(),
|
||||
hideMenuBar: await window.getHideMenuBar(),
|
||||
|
||||
notificationSetting: await window.getNotificationSetting(),
|
||||
audioNotification: await window.getAudioNotification(),
|
||||
|
||||
mediaPermissions: await window.getMediaPermissions(),
|
||||
|
||||
isPrimary: await window.isPrimary(),
|
||||
lastSyncTime: await window.getLastSyncTime(),
|
||||
});
|
||||
|
||||
window.initialRequest = getInitialData();
|
||||
window.initialRequest.then(data => {
|
||||
window.initialData = data;
|
||||
window.view = new Whisper.SettingsView();
|
||||
window.view.$el.appendTo($body);
|
||||
});
|
|
@ -14,8 +14,6 @@
|
|||
events: {
|
||||
'click .openInstaller': 'openInstaller', // NetworkStatusView has this button
|
||||
openInbox: 'openInbox',
|
||||
'change-theme': 'applyTheme',
|
||||
'change-hide-menu': 'applyHideMenu',
|
||||
},
|
||||
applyTheme: function() {
|
||||
var theme = storage.get('theme-setting') || 'android';
|
||||
|
|
69
js/views/clear_data_view.js
Normal file
69
js/views/clear_data_view.js
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* global i18n: false */
|
||||
/* global Whisper: false */
|
||||
|
||||
/* eslint-disable no-new */
|
||||
|
||||
// eslint-disable-next-line func-names
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
window.Whisper = window.Whisper || {};
|
||||
const { Database } = window.Whisper;
|
||||
const { Logs } = window.Signal;
|
||||
|
||||
const CLEAR_DATA_STEPS = {
|
||||
CHOICE: 1,
|
||||
DELETING: 2,
|
||||
};
|
||||
window.Whisper.ClearDataView = Whisper.View.extend({
|
||||
templateName: 'clear-data',
|
||||
className: 'full-screen-flow overlay',
|
||||
events: {
|
||||
'click .cancel': 'onCancel',
|
||||
'click .delete-all-data': 'onDeleteAllData',
|
||||
},
|
||||
initialize() {
|
||||
this.step = CLEAR_DATA_STEPS.CHOICE;
|
||||
},
|
||||
onCancel() {
|
||||
this.remove();
|
||||
},
|
||||
async onDeleteAllData() {
|
||||
console.log('Deleting everything!');
|
||||
this.step = CLEAR_DATA_STEPS.DELETING;
|
||||
this.render();
|
||||
|
||||
try {
|
||||
await Database.close();
|
||||
console.log('All database connections closed. Starting delete.');
|
||||
} catch (error) {
|
||||
console.log('Something went wrong closing all database connections.');
|
||||
}
|
||||
|
||||
this.clearAllData();
|
||||
},
|
||||
async clearAllData() {
|
||||
try {
|
||||
await Promise.all([Logs.deleteAll(), Database.drop()]);
|
||||
} catch (error) {
|
||||
console.log(
|
||||
'Something went wrong deleting all data:',
|
||||
error && error.stack ? error.stack : error
|
||||
);
|
||||
}
|
||||
window.restart();
|
||||
},
|
||||
render_attributes() {
|
||||
return {
|
||||
isStep1: this.step === CLEAR_DATA_STEPS.CHOICE,
|
||||
header: i18n('deleteAllDataHeader'),
|
||||
body: i18n('deleteAllDataBody'),
|
||||
cancelButton: i18n('cancel'),
|
||||
deleteButton: i18n('deleteAllDataButton'),
|
||||
|
||||
isStep2: this.step === CLEAR_DATA_STEPS.DELETING,
|
||||
deleting: i18n('deleteAllDataProgress'),
|
||||
};
|
||||
},
|
||||
});
|
||||
})();
|
|
@ -42,9 +42,8 @@
|
|||
close: i18n('gotIt'),
|
||||
debugLogExplanation: i18n('debugLogExplanation'),
|
||||
},
|
||||
close(e) {
|
||||
e.preventDefault();
|
||||
this.remove();
|
||||
close() {
|
||||
window.closeDebugLog();
|
||||
},
|
||||
async submit(e) {
|
||||
e.preventDefault();
|
||||
|
|
|
@ -233,13 +233,6 @@
|
|||
reloadBackgroundPage() {
|
||||
window.location.reload();
|
||||
},
|
||||
showSettings() {
|
||||
if (this.$el.find('.settings').length) {
|
||||
return;
|
||||
}
|
||||
const view = new Whisper.SettingsView();
|
||||
view.$el.appendTo(this.el);
|
||||
},
|
||||
filterContacts(e) {
|
||||
this.searchView.filterContacts(e);
|
||||
const input = this.$('input.search');
|
||||
|
|
|
@ -31,17 +31,25 @@
|
|||
if (this.recorder.isRecording()) {
|
||||
this.recorder.cancelRecording();
|
||||
}
|
||||
this.recorder = null;
|
||||
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
this.interval = null;
|
||||
|
||||
if (this.source) {
|
||||
this.source.disconnect();
|
||||
}
|
||||
this.source = null;
|
||||
|
||||
if (this.context) {
|
||||
this.context.close().then(function() {
|
||||
console.log('audio context closed');
|
||||
});
|
||||
}
|
||||
this.context = null;
|
||||
|
||||
this.remove();
|
||||
this.trigger('closed');
|
||||
},
|
||||
|
@ -74,8 +82,23 @@
|
|||
this.recorder.startRecording();
|
||||
},
|
||||
onError: function(error) {
|
||||
console.log(error.stack);
|
||||
// Protect against out-of-band errors, which can happen if the user revokes media
|
||||
// permissions after successfully accessing the microphone.
|
||||
if (!this.recorder) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.close();
|
||||
|
||||
if (error && error.name === 'PermissionDeniedError') {
|
||||
console.log('RecorderView.onError: Microphone access is not allowed!');
|
||||
window.showPermissionsPopup();
|
||||
} else {
|
||||
console.log(
|
||||
'RecorderView.onError:',
|
||||
error && error.stack ? error.stack : error
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -1,106 +1,119 @@
|
|||
/* global storage: false */
|
||||
/* global textsecure: false */
|
||||
/* global i18n: false */
|
||||
/* global Whisper: false */
|
||||
|
||||
/* eslint-disable */
|
||||
/* eslint-disable no-new */
|
||||
|
||||
// eslint-disable-next-line func-names
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
window.Whisper = window.Whisper || {};
|
||||
const { Database } = window.Whisper;
|
||||
const { OS, Logs } = window.Signal;
|
||||
const { Settings } = window.Signal.Types;
|
||||
|
||||
var CheckboxView = Whisper.View.extend({
|
||||
initialize: function(options) {
|
||||
this.name = options.name;
|
||||
this.defaultValue = options.defaultValue;
|
||||
this.event = options.event;
|
||||
const CheckboxView = Whisper.View.extend({
|
||||
initialize(options) {
|
||||
this.setFn = options.setFn;
|
||||
this.value = options.value;
|
||||
this.populate();
|
||||
},
|
||||
events: {
|
||||
change: 'change',
|
||||
},
|
||||
change: function(e) {
|
||||
var value = e.target.checked;
|
||||
storage.put(this.name, value);
|
||||
change(e) {
|
||||
const value = e.target.checked;
|
||||
this.setFn(value);
|
||||
console.log(this.name, 'changed to', value);
|
||||
if (this.event) {
|
||||
this.$el.trigger(this.event);
|
||||
}
|
||||
},
|
||||
populate: function() {
|
||||
var value = storage.get(this.name, this.defaultValue);
|
||||
this.$('input').prop('checked', !!value);
|
||||
populate() {
|
||||
this.$('input').prop('checked', !!this.value);
|
||||
},
|
||||
});
|
||||
var RadioButtonGroupView = Whisper.View.extend({
|
||||
initialize: function(options) {
|
||||
this.name = options.name;
|
||||
this.defaultValue = options.defaultValue;
|
||||
this.event = options.event;
|
||||
|
||||
const MediaPermissionsSettingView = Whisper.View.extend({
|
||||
initialize(options) {
|
||||
this.value = options.value;
|
||||
this.setFn = options.setFn;
|
||||
this.populate();
|
||||
},
|
||||
events: {
|
||||
change: 'change',
|
||||
},
|
||||
change: function(e) {
|
||||
var value = this.$(e.target).val();
|
||||
storage.put(this.name, value);
|
||||
console.log(this.name, 'changed to', value);
|
||||
if (this.event) {
|
||||
this.$el.trigger(this.event);
|
||||
}
|
||||
change(e) {
|
||||
this.value = e.target.checked;
|
||||
this.setFn(this.value);
|
||||
console.log('media-permissions changed to', this.value);
|
||||
},
|
||||
populate: function() {
|
||||
var value = storage.get(this.name, this.defaultValue);
|
||||
this.$('#' + this.name + '-' + value).attr('checked', 'checked');
|
||||
populate() {
|
||||
this.$('input').prop('checked', Boolean(this.value));
|
||||
},
|
||||
});
|
||||
|
||||
const RadioButtonGroupView = Whisper.View.extend({
|
||||
initialize(options) {
|
||||
this.name = options.name;
|
||||
this.setFn = options.setFn;
|
||||
this.value = options.value;
|
||||
this.populate();
|
||||
},
|
||||
events: {
|
||||
change: 'change',
|
||||
},
|
||||
change(e) {
|
||||
const value = this.$(e.target).val();
|
||||
this.setFn(value);
|
||||
console.log(this.name, 'changed to', value);
|
||||
},
|
||||
populate() {
|
||||
this.$(`#${this.name}-${this.value}`).attr('checked', 'checked');
|
||||
},
|
||||
});
|
||||
Whisper.SettingsView = Whisper.View.extend({
|
||||
className: 'settings modal expand',
|
||||
templateName: 'settings',
|
||||
initialize: function() {
|
||||
this.deviceName = textsecure.storage.user.getDeviceName();
|
||||
initialize() {
|
||||
this.render();
|
||||
new RadioButtonGroupView({
|
||||
el: this.$('.notification-settings'),
|
||||
defaultValue: 'message',
|
||||
name: 'notification-setting',
|
||||
value: window.initialData.notificationSetting,
|
||||
setFn: window.setNotificationSetting,
|
||||
});
|
||||
new RadioButtonGroupView({
|
||||
el: this.$('.theme-settings'),
|
||||
defaultValue: 'android',
|
||||
name: 'theme-setting',
|
||||
event: 'change-theme',
|
||||
value: window.initialData.themeSetting,
|
||||
setFn: window.setThemeSetting,
|
||||
});
|
||||
if (Settings.isAudioNotificationSupported()) {
|
||||
new CheckboxView({
|
||||
el: this.$('.audio-notification-setting'),
|
||||
defaultValue: false,
|
||||
name: 'audio-notification',
|
||||
value: window.initialData.audioNotification,
|
||||
setFn: window.setAudioNotification,
|
||||
});
|
||||
}
|
||||
new CheckboxView({
|
||||
el: this.$('.menu-bar-setting'),
|
||||
defaultValue: false,
|
||||
name: 'hide-menu-bar',
|
||||
event: 'change-hide-menu',
|
||||
value: window.initialData.hideMenuBar,
|
||||
setFn: window.setHideMenuBar,
|
||||
});
|
||||
if (textsecure.storage.user.getDeviceId() != '1') {
|
||||
var syncView = new SyncView().render();
|
||||
new MediaPermissionsSettingView({
|
||||
el: this.$('.media-permissions'),
|
||||
value: window.initialData.mediaPermissions,
|
||||
setFn: window.setMediaPermissions,
|
||||
});
|
||||
if (!window.initialData.isPrimary) {
|
||||
const syncView = new SyncView().render();
|
||||
this.$('.sync-setting').append(syncView.el);
|
||||
}
|
||||
},
|
||||
events: {
|
||||
'click .close': 'remove',
|
||||
'click .close': 'onClose',
|
||||
'click .clear-data': 'onClearData',
|
||||
},
|
||||
render_attributes: function() {
|
||||
render_attributes() {
|
||||
return {
|
||||
deviceNameLabel: i18n('deviceName'),
|
||||
deviceName: this.deviceName,
|
||||
deviceName: window.initialData.deviceName,
|
||||
theme: i18n('theme'),
|
||||
notifications: i18n('notifications'),
|
||||
notificationSettingsDialog: i18n('notificationSettingsDialog'),
|
||||
|
@ -116,121 +129,72 @@
|
|||
clearDataHeader: i18n('clearDataHeader'),
|
||||
clearDataButton: i18n('clearDataButton'),
|
||||
clearDataExplanation: i18n('clearDataExplanation'),
|
||||
permissions: i18n('permissions'),
|
||||
mediaPermissionsDescription: i18n('mediaPermissionsDescription'),
|
||||
};
|
||||
},
|
||||
onClearData: function() {
|
||||
var clearDataView = new ClearDataView().render();
|
||||
$('body').append(clearDataView.el);
|
||||
onClose() {
|
||||
window.closeSettings();
|
||||
},
|
||||
onClearData() {
|
||||
window.deleteAllData();
|
||||
window.closeSettings();
|
||||
},
|
||||
});
|
||||
|
||||
/* jshint ignore:start */
|
||||
/* eslint-enable */
|
||||
|
||||
const CLEAR_DATA_STEPS = {
|
||||
CHOICE: 1,
|
||||
DELETING: 2,
|
||||
};
|
||||
const ClearDataView = Whisper.View.extend({
|
||||
templateName: 'clear-data',
|
||||
className: 'full-screen-flow overlay',
|
||||
events: {
|
||||
'click .cancel': 'onCancel',
|
||||
'click .delete-all-data': 'onDeleteAllData',
|
||||
},
|
||||
initialize() {
|
||||
this.step = CLEAR_DATA_STEPS.CHOICE;
|
||||
},
|
||||
onCancel() {
|
||||
this.remove();
|
||||
},
|
||||
async onDeleteAllData() {
|
||||
console.log('Deleting everything!');
|
||||
this.step = CLEAR_DATA_STEPS.DELETING;
|
||||
this.render();
|
||||
|
||||
try {
|
||||
await Database.close();
|
||||
console.log('All database connections closed. Starting delete.');
|
||||
} catch (error) {
|
||||
console.log('Something went wrong closing all database connections.');
|
||||
}
|
||||
|
||||
this.clearAllData();
|
||||
},
|
||||
async clearAllData() {
|
||||
try {
|
||||
await Promise.all([Logs.deleteAll(), Database.drop()]);
|
||||
} catch (error) {
|
||||
console.log(
|
||||
'Something went wrong deleting all data:',
|
||||
error && error.stack ? error.stack : error
|
||||
);
|
||||
}
|
||||
window.restart();
|
||||
},
|
||||
render_attributes() {
|
||||
return {
|
||||
isStep1: this.step === CLEAR_DATA_STEPS.CHOICE,
|
||||
header: i18n('deleteAllDataHeader'),
|
||||
body: i18n('deleteAllDataBody'),
|
||||
cancelButton: i18n('cancel'),
|
||||
deleteButton: i18n('deleteAllDataButton'),
|
||||
|
||||
isStep2: this.step === CLEAR_DATA_STEPS.DELETING,
|
||||
deleting: i18n('deleteAllDataProgress'),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
/* eslint-disable */
|
||||
/* jshint ignore:end */
|
||||
|
||||
var SyncView = Whisper.View.extend({
|
||||
const SyncView = Whisper.View.extend({
|
||||
templateName: 'syncSettings',
|
||||
className: 'syncSettings',
|
||||
events: {
|
||||
'click .sync': 'sync',
|
||||
},
|
||||
enable: function() {
|
||||
initialize() {
|
||||
this.lastSyncTime = window.initialData.lastSyncTime;
|
||||
},
|
||||
enable() {
|
||||
this.$('.sync').text(i18n('syncNow'));
|
||||
this.$('.sync').removeAttr('disabled');
|
||||
},
|
||||
disable: function() {
|
||||
disable() {
|
||||
this.$('.sync').attr('disabled', 'disabled');
|
||||
this.$('.sync').text(i18n('syncing'));
|
||||
},
|
||||
onsuccess: function() {
|
||||
storage.put('synced_at', Date.now());
|
||||
onsuccess() {
|
||||
window.setLastSyncTime(Date.now());
|
||||
this.lastSyncTime = Date.now();
|
||||
console.log('sync successful');
|
||||
this.enable();
|
||||
this.render();
|
||||
},
|
||||
ontimeout: function() {
|
||||
ontimeout() {
|
||||
console.log('sync timed out');
|
||||
this.$('.synced_at').hide();
|
||||
this.$('.sync_failed').show();
|
||||
this.enable();
|
||||
},
|
||||
sync: function() {
|
||||
async sync() {
|
||||
this.$('.sync_failed').hide();
|
||||
if (textsecure.storage.user.getDeviceId() != '1') {
|
||||
this.disable();
|
||||
var syncRequest = window.getSyncRequest();
|
||||
syncRequest.addEventListener('success', this.onsuccess.bind(this));
|
||||
syncRequest.addEventListener('timeout', this.ontimeout.bind(this));
|
||||
} else {
|
||||
if (window.initialData.isPrimary) {
|
||||
console.log('Tried to sync from device 1');
|
||||
return;
|
||||
}
|
||||
|
||||
this.disable();
|
||||
try {
|
||||
await window.makeSyncRequest();
|
||||
this.onsuccess();
|
||||
} catch (error) {
|
||||
this.ontimeout();
|
||||
}
|
||||
},
|
||||
render_attributes: function() {
|
||||
var attrs = {
|
||||
render_attributes() {
|
||||
const attrs = {
|
||||
sync: i18n('sync'),
|
||||
syncNow: i18n('syncNow'),
|
||||
syncExplanation: i18n('syncExplanation'),
|
||||
syncFailed: i18n('syncFailed'),
|
||||
};
|
||||
var date = storage.get('synced_at');
|
||||
let date = this.lastSyncTime;
|
||||
if (date) {
|
||||
date = new Date(date);
|
||||
attrs.lastSynced = i18n('lastSynced');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue