diff --git a/js/signal.js b/js/signal.js new file mode 100644 index 000000000..468ca32b2 --- /dev/null +++ b/js/signal.js @@ -0,0 +1,128 @@ +// The idea with this file is to make it webpackable for the style guide + +const Backbone = require('../ts/backbone'); +const Crypto = require('./modules/crypto'); +const Database = require('./modules/database'); +const HTML = require('../ts/html'); +const Message = require('./modules/types/message'); +const Notifications = require('../ts/notifications'); +const OS = require('../ts/OS'); +const Settings = require('./modules/settings'); +const Startup = require('./modules/startup'); +const Util = require('../ts/util'); + +// Components +const { + ContactDetail, +} = require('../ts/components/conversation/ContactDetail'); +const { + EmbeddedContact, +} = require('../ts/components/conversation/EmbeddedContact'); +const { Lightbox } = require('../ts/components/Lightbox'); +const { LightboxGallery } = require('../ts/components/LightboxGallery'); +const { + MediaGallery, +} = require('../ts/components/conversation/media-gallery/MediaGallery'); +const { Quote } = require('../ts/components/conversation/Quote'); + +// Migrations +const { + getPlaceholderMigrations, +} = require('./modules/migrations/get_placeholder_migrations'); + +const Migrations0DatabaseWithAttachmentData = require('./modules/migrations/migrations_0_database_with_attachment_data'); +const Migrations1DatabaseWithoutAttachmentData = require('./modules/migrations/migrations_1_database_without_attachment_data'); + +// Types +const AttachmentType = require('./modules/types/attachment'); +const Contact = require('../ts/types/Contact'); +const Conversation = require('../ts/types/Conversation'); +const Errors = require('./modules/types/errors'); +const MediaGalleryMessage = require('../ts/components/conversation/media-gallery/types/Message'); +const MIME = require('../ts/types/MIME'); +const SettingsType = require('../ts/types/Settings'); + +// Views +const Initialization = require('./modules/views/initialization'); + +// Workflow +const { IdleDetector } = require('./modules/idle_detector'); +const MessageDataMigrator = require('./modules/messages_data_migrator'); + +exports.setup = (options = {}) => { + const { Attachments, userDataPath } = options; + + const Components = { + ContactDetail, + EmbeddedContact, + Lightbox, + LightboxGallery, + MediaGallery, + Types: { + Message: MediaGalleryMessage, + }, + Quote, + }; + + const attachmentsPath = Attachments.getPath(userDataPath); + const readAttachmentData = Attachments.createReader(attachmentsPath); + const loadAttachmentData = AttachmentType.loadData(readAttachmentData); + + const Migrations = { + attachmentsPath, + deleteAttachmentData: AttachmentType.deleteData( + Attachments.createDeleter(attachmentsPath) + ), + getAbsoluteAttachmentPath: Attachments.createAbsolutePathGetter( + attachmentsPath + ), + getPlaceholderMigrations, + loadAttachmentData, + loadMessage: Message.createAttachmentLoader(loadAttachmentData), + Migrations0DatabaseWithAttachmentData, + Migrations1DatabaseWithoutAttachmentData, + upgradeMessageSchema: message => + Message.upgradeSchema(message, { + writeNewAttachmentData: Attachments.createWriterForNew(attachmentsPath), + }), + writeMessageAttachments: Message.createAttachmentDataWriter( + Attachments.createWriterForExisting(attachmentsPath) + ), + }; + + const Types = { + Attachment: AttachmentType, + Contact, + Conversation, + Errors, + Message, + MIME, + Settings: SettingsType, + }; + + const Views = { + Initialization, + }; + + const Workflow = { + IdleDetector, + MessageDataMigrator, + }; + + return { + Backbone, + Components, + Crypto, + Database, + HTML, + Migrations, + Notifications, + OS, + Settings, + Startup, + Types, + Util, + Views, + Workflow, + }; +}; diff --git a/preload.js b/preload.js index 3ea16a47f..a225f9eae 100644 --- a/preload.js +++ b/preload.js @@ -5,9 +5,6 @@ console.log('preload'); const electron = require('electron'); -const Attachment = require('./js/modules/types/attachment'); -const Attachments = require('./app/attachments'); -const Message = require('./js/modules/types/message'); const { deferredToPromise } = require('./js/modules/deferred_to_promise'); const { app } = electron.remote; @@ -114,10 +111,12 @@ window.React = require('react'); window.ReactDOM = require('react-dom'); window.moment = require('moment'); -const { setup } = require('./js/modules/i18n'); +const Signal = require('./js/signal'); +const i18n = require('./js/modules/i18n'); +const Attachments = require('./app/attachments'); const { locale, localeMessages } = window.config; -window.i18n = setup(locale, localeMessages); +window.i18n = i18n.setup(locale, localeMessages); window.moment.updateLocale(locale, { relativeTime: { s: window.i18n('timestamp_s'), @@ -127,107 +126,16 @@ window.moment.updateLocale(locale, { }); window.moment.locale(locale); -// ES2015+ modules -const attachmentsPath = Attachments.getPath(app.getPath('userData')); -const getAbsoluteAttachmentPath = Attachments.createAbsolutePathGetter( - attachmentsPath -); -const deleteAttachmentData = Attachments.createDeleter(attachmentsPath); -const readAttachmentData = Attachments.createReader(attachmentsPath); -const writeNewAttachmentData = Attachments.createWriterForNew(attachmentsPath); -const writeExistingAttachmentData = Attachments.createWriterForExisting( - attachmentsPath -); - -const loadAttachmentData = Attachment.loadData(readAttachmentData); - -// Injected context functions to keep `Message` agnostic from Electron: -const upgradeSchemaContext = { - writeNewAttachmentData, -}; -const upgradeMessageSchema = message => - Message.upgradeSchema(message, upgradeSchemaContext); - -const { - getPlaceholderMigrations, -} = require('./js/modules/migrations/get_placeholder_migrations'); -const { IdleDetector } = require('./js/modules/idle_detector'); +window.Signal = Signal.setup({ + Attachments, + userDataPath: app.getPath('userData'), +}); -window.Signal = {}; -window.Signal.Backbone = require('./ts/backbone'); +// Pulling these in separately since they access filesystem, electron window.Signal.Backup = require('./js/modules/backup'); -window.Signal.Crypto = require('./js/modules/crypto'); -window.Signal.Database = require('./js/modules/database'); window.Signal.Debug = require('./js/modules/debug'); -window.Signal.HTML = require('./ts/html'); window.Signal.Logs = require('./js/modules/logs'); -// React components -const { Lightbox } = require('./ts/components/Lightbox'); -const { LightboxGallery } = require('./ts/components/LightboxGallery'); -const { - MediaGallery, -} = require('./ts/components/conversation/media-gallery/MediaGallery'); -const { Quote } = require('./ts/components/conversation/Quote'); -const { - EmbeddedContact, -} = require('./ts/components/conversation/EmbeddedContact'); -const { ContactDetail } = require('./ts/components/conversation/ContactDetail'); - -const MediaGalleryMessage = require('./ts/components/conversation/media-gallery/types/Message'); - -window.Signal.Components = { - ContactDetail, - EmbeddedContact, - Lightbox, - LightboxGallery, - MediaGallery, - Types: { - Message: MediaGalleryMessage, - }, - Quote, -}; - -window.Signal.Migrations = {}; -window.Signal.Migrations.deleteAttachmentData = Attachment.deleteData( - deleteAttachmentData -); -window.Signal.Migrations.getPlaceholderMigrations = getPlaceholderMigrations; -window.Signal.Migrations.writeMessageAttachments = Message.createAttachmentDataWriter( - writeExistingAttachmentData -); -window.Signal.Migrations.getAbsoluteAttachmentPath = getAbsoluteAttachmentPath; -window.Signal.Migrations.loadAttachmentData = loadAttachmentData; -window.Signal.Migrations.loadMessage = Message.createAttachmentLoader( - loadAttachmentData -); -window.Signal.Migrations.Migrations0DatabaseWithAttachmentData = require('./js/modules/migrations/migrations_0_database_with_attachment_data'); -window.Signal.Migrations.Migrations1DatabaseWithoutAttachmentData = require('./js/modules/migrations/migrations_1_database_without_attachment_data'); - -window.Signal.Migrations.upgradeMessageSchema = upgradeMessageSchema; -window.Signal.Notifications = require('./ts/notifications'); -window.Signal.OS = require('./ts/OS'); -window.Signal.Settings = require('./js/modules/settings'); -window.Signal.Startup = require('./js/modules/startup'); - -window.Signal.Types = {}; -window.Signal.Types.Attachment = Attachment; -window.Signal.Types.Contact = require('./ts/types/Contact'); -window.Signal.Types.Conversation = require('./ts/types/Conversation'); -window.Signal.Types.Errors = require('./js/modules/types/errors'); - -window.Signal.Types.Message = Message; -window.Signal.Types.MIME = require('./ts/types/MIME'); -window.Signal.Types.Settings = require('./ts/types/Settings'); -window.Signal.Util = require('./ts/util'); - -window.Signal.Views = {}; -window.Signal.Views.Initialization = require('./js/modules/views/initialization'); - -window.Signal.Workflow = {}; -window.Signal.Workflow.IdleDetector = IdleDetector; -window.Signal.Workflow.MessageDataMigrator = require('./js/modules/messages_data_migrator'); - // We pull this in last, because the native module involved appears to be sensitive to // /tmp mounted as noexec on Linux. require('./js/spell_check'); @@ -240,7 +148,7 @@ if (window.config.environment === 'test') { tmp: require('tmp'), path: require('path'), basePath: __dirname, - attachmentsPath, + attachmentsPath: window.Signal.Migrations.attachmentsPath, }; /* eslint-enable global-require, import/no-extraneous-dependencies */ } diff --git a/ts/styleguide/StyleGuideUtil.ts b/ts/styleguide/StyleGuideUtil.ts index 37ee9699d..5fdd2cdef 100644 --- a/ts/styleguide/StyleGuideUtil.ts +++ b/ts/styleguide/StyleGuideUtil.ts @@ -15,17 +15,9 @@ export { _ }; export { ConversationContext } from './ConversationContext'; export { BackboneWrapper } from '../components/utility/BackboneWrapper'; -// Here we can make things inside Webpack available to Backbone views like preload.js. - -import { Quote } from '../components/conversation/Quote'; -import { EmbeddedContact } from '../components/conversation/EmbeddedContact'; -import * as Contact from '../types/Contact'; - -import * as HTML from '../html'; - -import * as Attachment from '../../ts/types/Attachment'; -import * as MIME from '../../ts/types/MIME'; -import { SignalService } from '../../ts/protobuf'; +// @ts-ignore +import * as Signal from '../../js/signal'; +import { SignalService } from '../protobuf'; // TypeScript wants two things when you import: // 1) a normal typescript file @@ -107,14 +99,15 @@ import localeMessages from '../../_locales/en/messages.json'; // @ts-ignore import { setup } from '../../js/modules/i18n'; -import * as Util from '../util'; import filesize from 'filesize'; const i18n = setup(locale, localeMessages); -export { theme, locale, i18n }; +parent.filesize = filesize; parent.i18n = i18n; +parent.React = React; +parent.ReactDOM = ReactDOM; parent.moment = moment; parent.moment.updateLocale(locale, { @@ -126,20 +119,26 @@ parent.moment.updateLocale(locale, { }); parent.moment.locale(locale); -parent.React = React; -parent.ReactDOM = ReactDOM; +export { theme, locale, i18n }; -parent.Signal.HTML = HTML; -parent.Signal.Types.MIME = MIME; -parent.Signal.Types.Attachment = Attachment; -parent.Signal.Types.Contact = Contact; -parent.Signal.Components = { - Quote, - EmbeddedContact, +// Used by signal.js to set up code that deals with message attachments/avatars +const Attachments = { + createAbsolutePathGetter: () => () => '/fake/path', + createDeleter: () => async () => undefined, + createReader: () => async () => new ArrayBuffer(10), + createWriterForExisting: () => async () => '/fake/path', + createWriterForNew: () => async () => ({ + data: new ArrayBuffer(10), + path: '/fake/path', + }), + getPath: (path: string) => path, }; -parent.Signal.Util = Util; + +parent.Signal = Signal.setup({ + Attachments, + userDataPath: '/', +}); parent.SignalService = SignalService; -parent.filesize = filesize; parent.ConversationController._initialFetchComplete = true; parent.ConversationController._initialPromise = Promise.resolve();