Turn on prettier support for markdown files, update all files
This commit is contained in:
parent
47468ee3db
commit
322d307655
13 changed files with 782 additions and 971 deletions
20
.github/ISSUE_TEMPLATE.md
vendored
20
.github/ISSUE_TEMPLATE.md
vendored
|
@ -12,34 +12,34 @@ locations if you have a question or comment:
|
||||||
Lastly, be sure to preview your issue before saving. Thanks!
|
Lastly, be sure to preview your issue before saving. Thanks!
|
||||||
-->
|
-->
|
||||||
|
|
||||||
- [ ] I have searched open and closed issues for duplicates
|
* [ ] I have searched open and closed issues for duplicates
|
||||||
<!--
|
<!--
|
||||||
You can search all issues here:
|
You can search all issues here:
|
||||||
https://github.com/WhisperSystems/Signal-Desktop/issues?utf8=%E2%9C%93&q=is%3Aissue
|
https://github.com/WhisperSystems/Signal-Desktop/issues?utf8=%E2%9C%93&q=is%3Aissue
|
||||||
Replace [ ] with [X] once you've searched
|
Replace [ ] with [X] once you've searched
|
||||||
-->
|
-->
|
||||||
|
|
||||||
----------------------------------------
|
---
|
||||||
|
|
||||||
### Bug description
|
### Bug description
|
||||||
|
|
||||||
<!-- Give an overall summary of the issue. -->
|
<!-- Give an overall summary of the issue. -->
|
||||||
|
|
||||||
|
|
||||||
### Steps to reproduce
|
### Steps to reproduce
|
||||||
|
|
||||||
<!-- Using bullet points, list the steps that reproduce the bug. -->
|
<!-- Using bullet points, list the steps that reproduce the bug. -->
|
||||||
|
|
||||||
1.
|
1. step one
|
||||||
2.
|
2. step two
|
||||||
3.
|
3. step three
|
||||||
|
|
||||||
Actual result:
|
Actual result:
|
||||||
|
|
||||||
<!-- Describe the details of the buggy behaviour. -->
|
<!-- Describe the details of the buggy behaviour. -->
|
||||||
|
|
||||||
Expected result:
|
Expected result:
|
||||||
<!-- Describe in detail what the correct behavior should be. -->
|
|
||||||
|
|
||||||
|
<!-- Describe in detail what the correct behavior should be. -->
|
||||||
|
|
||||||
### Screenshots
|
### Screenshots
|
||||||
|
|
||||||
|
@ -48,19 +48,19 @@ How to take screenshots on all OSes: https://www.take-a-screenshot.org/
|
||||||
You can drag and drop images into this text box.
|
You can drag and drop images into this text box.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
### Platform info
|
### Platform info
|
||||||
|
|
||||||
|
|
||||||
Signal version:
|
Signal version:
|
||||||
|
|
||||||
<!-- You can see Signal's version number at Help -> About or File -> About Signal Desktop -->
|
<!-- You can see Signal's version number at Help -> About or File -> About Signal Desktop -->
|
||||||
|
|
||||||
Operating System:
|
Operating System:
|
||||||
|
|
||||||
<!-- Instructions for finding your OS version are here: http://whatsmyos.com/ -->
|
<!-- Instructions for finding your OS version are here: http://whatsmyos.com/ -->
|
||||||
|
|
||||||
Linked device version:
|
Linked device version:
|
||||||
<!-- Android: Settings -> Advanced, iOS: Settings -> General -> About -->
|
|
||||||
|
|
||||||
|
<!-- Android: Settings -> Advanced, iOS: Settings -> General -> About -->
|
||||||
|
|
||||||
### Link to debug log
|
### Link to debug log
|
||||||
|
|
||||||
|
|
14
.github/PULL_REQUEST_TEMPLATE.md
vendored
14
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -8,17 +8,17 @@ Remember, you can preview this before saving it.
|
||||||
<!-- You can remove this first section if you have contributed before -->
|
<!-- You can remove this first section if you have contributed before -->
|
||||||
|
|
||||||
### First time contributor checklist:
|
### First time contributor checklist:
|
||||||
- [ ] I have read the [README](https://github.com/WhisperSystems/Signal-Desktop/blob/master/README.md) and [Contributor Guidelines](https://github.com/WhisperSystems/Signal-Desktop/blob/master/CONTRIBUTING.md)
|
|
||||||
- [ ] I have signed the [Contributor Licence Agreement](https://whispersystems.org/cla/)
|
|
||||||
|
|
||||||
|
* [ ] I have read the [README](https://github.com/WhisperSystems/Signal-Desktop/blob/master/README.md) and [Contributor Guidelines](https://github.com/WhisperSystems/Signal-Desktop/blob/master/CONTRIBUTING.md)
|
||||||
|
* [ ] I have signed the [Contributor Licence Agreement](https://whispersystems.org/cla/)
|
||||||
|
|
||||||
### Contributor checklist:
|
### Contributor checklist:
|
||||||
- [ ] My contribution is **not** related to translations. _Please submit translation changes via our [Signal Desktop Transifex project](https://www.transifex.com/liliakai/signal-desktop/)._
|
|
||||||
- [ ] My commits are in nice logical chunks with [good commit messages](http://chris.beams.io/posts/git-commit/)
|
|
||||||
- [ ] My changes are [rebased](https://medium.freecodecamp.org/git-rebase-and-the-golden-rule-explained-70715eccc372) on the latest [`development`](https://github.com/WhisperSystems/Signal-Desktop/tree/development) branch
|
|
||||||
- [ ] My changes pass 100% of [local tests](https://github.com/WhisperSystems/Signal-Desktop/blob/master/CONTRIBUTING.md#tests)
|
|
||||||
- [ ] My changes are ready to be shipped to users
|
|
||||||
|
|
||||||
|
* [ ] My contribution is **not** related to translations. _Please submit translation changes via our [Signal Desktop Transifex project](https://www.transifex.com/liliakai/signal-desktop/)._
|
||||||
|
* [ ] My commits are in nice logical chunks with [good commit messages](http://chris.beams.io/posts/git-commit/)
|
||||||
|
* [ ] My changes are [rebased](https://medium.freecodecamp.org/git-rebase-and-the-golden-rule-explained-70715eccc372) on the latest [`development`](https://github.com/WhisperSystems/Signal-Desktop/tree/development) branch
|
||||||
|
* [ ] My changes pass 100% of [local tests](https://github.com/WhisperSystems/Signal-Desktop/blob/master/CONTRIBUTING.md#tests)
|
||||||
|
* [ ] My changes are ready to be shipped to users
|
||||||
|
|
||||||
### Description
|
### Description
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
Contributor Guidelines
|
# Contributor Guidelines
|
||||||
======================
|
|
||||||
|
|
||||||
## Advice for new contributors
|
## Advice for new contributors
|
||||||
|
|
||||||
|
@ -20,7 +19,6 @@ Once you've spent a little bit of time planning your solution, it's a good idea
|
||||||
back to the issue and talk about your approach. We'd be happy to provide feedback. [An
|
back to the issue and talk about your approach. We'd be happy to provide feedback. [An
|
||||||
ounce of prevention, as they say!](https://www.goodreads.com/quotes/247269-an-ounce-of-prevention-is-worth-a-pound-of-cure)
|
ounce of prevention, as they say!](https://www.goodreads.com/quotes/247269-an-ounce-of-prevention-is-worth-a-pound-of-cure)
|
||||||
|
|
||||||
|
|
||||||
## Developer Setup
|
## Developer Setup
|
||||||
|
|
||||||
First, you'll need [Node.js](https://nodejs.org/) which matches our current version.
|
First, you'll need [Node.js](https://nodejs.org/) which matches our current version.
|
||||||
|
@ -33,7 +31,7 @@ Then you need `git`, if you don't have that yet: https://git-scm.com/
|
||||||
|
|
||||||
And for the final step before we actually get started, you'll need build tools to install
|
And for the final step before we actually get started, you'll need build tools to install
|
||||||
the native modules used by the application. On Windows, it's easiest to open the [Command
|
the native modules used by the application. On Windows, it's easiest to open the [Command
|
||||||
Prompt (`cmd.exe`) as Administrator](https://technet.microsoft.com/en-us/library/cc947813(v=ws.10).aspx)
|
Prompt (`cmd.exe`) as Administrator](<https://technet.microsoft.com/en-us/library/cc947813(v=ws.10).aspx>)
|
||||||
and run this:
|
and run this:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -78,7 +76,6 @@ Fear not! You don't have to link the app with your phone. During setup in develo
|
||||||
mode, you'll be presented with a 'Standalone' button which goes through the registration
|
mode, you'll be presented with a 'Standalone' button which goes through the registration
|
||||||
process like you would on a phone. But you won't be linked to any other devices.
|
process like you would on a phone. But you won't be linked to any other devices.
|
||||||
|
|
||||||
|
|
||||||
## The staging environment
|
## The staging environment
|
||||||
|
|
||||||
Sadly, this default setup results in no contacts and no message history, an entirely
|
Sadly, this default setup results in no contacts and no message history, an entirely
|
||||||
|
@ -86,9 +83,10 @@ empty application. But you can use the information from your production install
|
||||||
Desktop to populate your testing application!
|
Desktop to populate your testing application!
|
||||||
|
|
||||||
First, find your application data:
|
First, find your application data:
|
||||||
- OSX: `~/Library/Application Support/Signal`
|
|
||||||
- Linux: `~/.config/Signal`
|
* OSX: `~/Library/Application Support/Signal`
|
||||||
- Windows 10: `C:\Users\<YourName>\AppData\Roaming\Signal`
|
* Linux: `~/.config/Signal`
|
||||||
|
* Windows 10: `C:\Users\<YourName>\AppData\Roaming\Signal`
|
||||||
|
|
||||||
Now make a copy of this production data directory in the same place, and call it
|
Now make a copy of this production data directory in the same place, and call it
|
||||||
`Signal-development`. Now start up the development version of the app as normal,
|
`Signal-development`. Now start up the development version of the app as normal,
|
||||||
|
@ -105,7 +103,6 @@ message history and contact list.
|
||||||
Here's the catch: you can't message any of these contacts, since they haven't done the
|
Here's the catch: you can't message any of these contacts, since they haven't done the
|
||||||
same thing. Who can you message for testing?
|
same thing. Who can you message for testing?
|
||||||
|
|
||||||
|
|
||||||
## Additional storage profiles
|
## Additional storage profiles
|
||||||
|
|
||||||
What you need for proper testing is additional phone numbers, to register additional
|
What you need for proper testing is additional phone numbers, to register additional
|
||||||
|
@ -134,13 +131,11 @@ NODE_APP_INSTANCE=alice yarn run start
|
||||||
This changes the [userData](https://electron.atom.io/docs/all/#appgetpathname)
|
This changes the [userData](https://electron.atom.io/docs/all/#appgetpathname)
|
||||||
directory from `%appData%/Signal` to `%appData%/Signal-aliceProfile`.
|
directory from `%appData%/Signal` to `%appData%/Signal-aliceProfile`.
|
||||||
|
|
||||||
|
|
||||||
# Making changes
|
# Making changes
|
||||||
|
|
||||||
So you're in the process of preparing that pull request. Here's how to make that go
|
So you're in the process of preparing that pull request. Here's how to make that go
|
||||||
smoothly.
|
smoothly.
|
||||||
|
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
Please write tests! Our testing framework is
|
Please write tests! Our testing framework is
|
||||||
|
@ -200,7 +195,6 @@ Above all, spend some time with the repository. Follow the pull request template
|
||||||
your pull request description automatically. Take a look at recent approved pull requests,
|
your pull request description automatically. Take a look at recent approved pull requests,
|
||||||
see how they did things.
|
see how they did things.
|
||||||
|
|
||||||
|
|
||||||
## Linking to a staging mobile device
|
## Linking to a staging mobile device
|
||||||
|
|
||||||
Multiple standalone desktop devices are great for testing of a lot of scenarios. But a lot
|
Multiple standalone desktop devices are great for testing of a lot of scenarios. But a lot
|
||||||
|
@ -226,7 +220,6 @@ Then you can set up your development build of Signal Desktop as normal. If you'v
|
||||||
set up as a standalone install, you can switch by opening the DevTools (View -> Toggle
|
set up as a standalone install, you can switch by opening the DevTools (View -> Toggle
|
||||||
Developer Tools) and entering this into the Console and pressing enter: `window.owsDesktopApp.appView.openInstaller();`
|
Developer Tools) and entering this into the Console and pressing enter: `window.owsDesktopApp.appView.openInstaller();`
|
||||||
|
|
||||||
|
|
||||||
## Changing to production
|
## Changing to production
|
||||||
|
|
||||||
If you're completely sure that your changes will have no impact to the production servers,
|
If you're completely sure that your changes will have no impact to the production servers,
|
||||||
|
@ -244,16 +237,16 @@ you can connect your development build to the production server by putting a fil
|
||||||
production servers will _unregister_ your mobile device! All messages from your contacts
|
production servers will _unregister_ your mobile device! All messages from your contacts
|
||||||
will go to your new development desktop app instead of your phone.
|
will go to your new development desktop app instead of your phone.
|
||||||
|
|
||||||
|
|
||||||
## Testing Production Builds
|
## Testing Production Builds
|
||||||
|
|
||||||
To test changes to the build system, build a release using
|
To test changes to the build system, build a release using
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn generate
|
yarn generate
|
||||||
yarn build-release
|
yarn build-release
|
||||||
```
|
```
|
||||||
Then, run the tests using `grunt test-release:osx --dir=release`, replacing `osx` with `linux` or `win` depending on your platform.
|
|
||||||
|
|
||||||
|
Then, run the tests using `grunt test-release:osx --dir=release`, replacing `osx` with `linux` or `win` depending on your platform.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
|
@ -265,11 +258,11 @@ npm, then run `npm install` to install bower, grunt, and related plugins.
|
||||||
|
|
||||||
### Adding a bower component
|
### Adding a bower component
|
||||||
|
|
||||||
Add the package name and version to bower.json under 'dependencies' or `bower
|
Add the package name and version to bower.json under 'dependencies' or `bower install package-name --save`
|
||||||
install package-name --save`
|
|
||||||
|
|
||||||
Next update the "preen" config in bower.json with the list of files we will
|
Next update the "preen" config in bower.json with the list of files we will
|
||||||
actually use from the new package, e.g.:
|
actually use from the new package, e.g.:
|
||||||
|
|
||||||
```
|
```
|
||||||
"preen": {
|
"preen": {
|
||||||
"package-name": [
|
"package-name": [
|
||||||
|
@ -279,6 +272,7 @@ actually use from the new package, e.g.:
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If you'd like to add the new dependency to js/components.js to be included on
|
If you'd like to add the new dependency to js/components.js to be included on
|
||||||
all html pages, simply append the package name to the concat.app list in
|
all html pages, simply append the package name to the concat.app list in
|
||||||
`bower.json`. Take care to insert it in the order you would like it
|
`bower.json`. Take care to insert it in the order you would like it
|
||||||
|
|
14
README.md
14
README.md
|
@ -12,40 +12,36 @@ Signal Desktop is an Electron application that links with your
|
||||||
|
|
||||||
You can install it on a computer which already has the production version installed. It uses different data and install locations.
|
You can install it on a computer which already has the production version installed. It uses different data and install locations.
|
||||||
|
|
||||||
- _Windows:_ You can find the most recent build here: https://updates.signal.org/desktop/beta.yml
|
* _Windows:_ You can find the most recent build here: https://updates.signal.org/desktop/beta.yml
|
||||||
- _Mac:_ You can find the most recent build here: https://updates.signal.org/desktop/beta-mac.yml
|
* _Mac:_ You can find the most recent build here: https://updates.signal.org/desktop/beta-mac.yml
|
||||||
- _Linux:_ same instructions as the production install steps linked above, but run `apt-get install signal-desktop-beta` instead
|
* _Linux:_ same instructions as the production install steps linked above, but run `apt-get install signal-desktop-beta` instead
|
||||||
|
|
||||||
|
|
||||||
## Got a question?
|
## Got a question?
|
||||||
|
|
||||||
You can find answers to a number of frequently asked questions on our support site: https://support.signal.org/.
|
You can find answers to a number of frequently asked questions on our support site: https://support.signal.org/.
|
||||||
The community forum is another good place for questions: https://community.signalusers.org/.
|
The community forum is another good place for questions: https://community.signalusers.org/.
|
||||||
|
|
||||||
|
|
||||||
## Found a Bug? Have a feature request?
|
## Found a Bug? Have a feature request?
|
||||||
|
|
||||||
Please search the existing issues for your bug and create a new one if the issue is not yet tracked!
|
Please search the existing issues for your bug and create a new one if the issue is not yet tracked!
|
||||||
|
|
||||||
https://github.com/signalapp/Signal-Desktop/issues
|
https://github.com/signalapp/Signal-Desktop/issues
|
||||||
|
|
||||||
|
|
||||||
## Contributing Translations
|
## Contributing Translations
|
||||||
|
|
||||||
Interested in helping to translate Signal? Contribute here:
|
Interested in helping to translate Signal? Contribute here:
|
||||||
|
|
||||||
https://www.transifex.com/projects/p/signal-desktop
|
https://www.transifex.com/projects/p/signal-desktop
|
||||||
|
|
||||||
|
|
||||||
## Contributing Code
|
## Contributing Code
|
||||||
|
|
||||||
Please see [CONTRIBUTING.md](https://github.com/signalapp/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
|
for setup instructions and contributor guidelines. And don't forget to sign the
|
||||||
[CLA](https://signal.org/cla/).
|
[CLA](https://signal.org/cla/).
|
||||||
|
|
||||||
|
|
||||||
## Contributing Funds
|
## Contributing Funds
|
||||||
You can donate to Signal development through the [Freedom of the Press Foundation](https://freedom.press/crowdfunding/signal/).
|
|
||||||
|
|
||||||
|
You can donate to Signal development through the [Freedom of the Press Foundation](https://freedom.press/crowdfunding/signal/).
|
||||||
|
|
||||||
## Cryptography Notice
|
## Cryptography Notice
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
"lint": "yarn format --list-different && yarn lint-windows",
|
"lint": "yarn format --list-different && yarn lint-windows",
|
||||||
"lint-windows": "yarn eslint && yarn grunt lint && yarn tslint",
|
"lint-windows": "yarn eslint && yarn grunt lint && yarn tslint",
|
||||||
"tslint": "tslint --config tslint.json --format stylish --project .",
|
"tslint": "tslint --config tslint.json --format stylish --project .",
|
||||||
"format": "prettier --write \"*.js\" \"js/**/*.js\" \"ts/**/*.{ts,tsx}\" \"test/**/*.js\"",
|
"format": "prettier --write \"*.js\" \"js/**/*.js\" \"ts/**/*.{ts,tsx}\" \"test/**/*.js\" \"*.md\" \"./**/*.md\"",
|
||||||
"transpile": "tsc",
|
"transpile": "tsc",
|
||||||
"clean-transpile": "rimraf ts/**/*.js ts/*.js",
|
"clean-transpile": "rimraf ts/**/*.js ts/*.js",
|
||||||
"open-coverage": "open coverage/lcov-report/index.html",
|
"open-coverage": "open coverage/lcov-report/index.html",
|
||||||
|
|
|
@ -9,5 +9,5 @@ const noop = () => {};
|
||||||
onPrevious={noop}
|
onPrevious={noop}
|
||||||
onSave={noop}
|
onSave={noop}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>;
|
||||||
```
|
```
|
||||||
|
|
|
@ -11,9 +11,6 @@ const items = [
|
||||||
];
|
];
|
||||||
|
|
||||||
<div style={{ position: 'relative', width: '100%', height: 500 }}>
|
<div style={{ position: 'relative', width: '100%', height: 500 }}>
|
||||||
<LightboxGallery
|
<LightboxGallery items={items} onSave={noop} />
|
||||||
items={items}
|
</div>;
|
||||||
onSave={noop}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
Placeholder component:
|
Placeholder component:
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
|
@ -17,21 +16,17 @@ const outgoing = new Whisper.Message({
|
||||||
body: 'How are you doing this fine day?',
|
body: 'How are you doing this fine day?',
|
||||||
sent_at: Date.now() - 18000,
|
sent_at: Date.now() - 18000,
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### In a group conversation
|
### In a group conversation
|
||||||
|
@ -42,21 +37,17 @@ const outgoing = new Whisper.Message({
|
||||||
body: 'How are you doing this fine day?',
|
body: 'How are you doing this fine day?',
|
||||||
sent_at: Date.now() - 200000,
|
sent_at: Date.now() - 200000,
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme} type="group">
|
<util.ConversationContext theme={util.theme} type="group">
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### With an error
|
### With an error
|
||||||
|
@ -72,22 +63,18 @@ const outgoing = new Whisper.Message({
|
||||||
sent_at: Date.now() - 200000,
|
sent_at: Date.now() - 200000,
|
||||||
errors: [error],
|
errors: [error],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
body: null,
|
body: null,
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Network error (outgoing only)
|
#### Network error (outgoing only)
|
||||||
|
@ -104,11 +91,8 @@ const outgoing = new Whisper.Message({
|
||||||
});
|
});
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme} type="group">
|
<util.ConversationContext theme={util.theme} type="group">
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
View={View}
|
</util.ConversationContext>;
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Network error, partial send in group (outgoing only)
|
#### Network error, partial send in group (outgoing only)
|
||||||
|
@ -126,11 +110,8 @@ const outgoing = new Whisper.Message({
|
||||||
});
|
});
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme} type="group">
|
<util.ConversationContext theme={util.theme} type="group">
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
View={View}
|
</util.ConversationContext>;
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### No message contents
|
#### No message contents
|
||||||
|
@ -140,22 +121,18 @@ const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
sent_at: Date.now() - 200000,
|
sent_at: Date.now() - 200000,
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Disappearing
|
### Disappearing
|
||||||
|
@ -168,22 +145,18 @@ const outgoing = new Whisper.Message({
|
||||||
expirationStartTimestamp: Date.now() - 1000,
|
expirationStartTimestamp: Date.now() - 1000,
|
||||||
body: 'This message will self-destruct in two minutes',
|
body: 'This message will self-destruct in two minutes',
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Notfications
|
### Notfications
|
||||||
|
@ -200,7 +173,7 @@ const fromOther = new Whisper.Message({
|
||||||
expirationStartTimestamp: Date.now() - 1000,
|
expirationStartTimestamp: Date.now() - 1000,
|
||||||
expirationTimerUpdate: {
|
expirationTimerUpdate: {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const fromUpdate = new Whisper.Message({
|
const fromUpdate = new Whisper.Message({
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
|
@ -212,7 +185,7 @@ const fromUpdate = new Whisper.Message({
|
||||||
expirationTimerUpdate: {
|
expirationTimerUpdate: {
|
||||||
fromSync: true,
|
fromSync: true,
|
||||||
source: util.ourNumber,
|
source: util.ourNumber,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const fromMe = new Whisper.Message({
|
const fromMe = new Whisper.Message({
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
|
@ -223,23 +196,14 @@ const fromMe = new Whisper.Message({
|
||||||
expirationStartTimestamp: Date.now() - 1000,
|
expirationStartTimestamp: Date.now() - 1000,
|
||||||
expirationTimerUpdate: {
|
expirationTimerUpdate: {
|
||||||
source: util.ourNumber,
|
source: util.ourNumber,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
const View = Whisper.ExpirationTimerUpdateView;
|
const View = Whisper.ExpirationTimerUpdateView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: fromOther }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: fromUpdate }} />
|
||||||
options={{ model: fromOther }}
|
<util.BackboneWrapper View={View} options={{ model: fromMe }} />
|
||||||
/>
|
</util.ConversationContext>;
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: fromUpdate }}
|
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: fromMe }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Safety number change
|
#### Safety number change
|
||||||
|
@ -252,11 +216,8 @@ const incoming = new Whisper.Message({
|
||||||
});
|
});
|
||||||
const View = Whisper.KeyChangeView;
|
const View = Whisper.KeyChangeView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
</util.ConversationContext>;
|
||||||
options={{ model: incoming }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Marking as verified
|
#### Marking as verified
|
||||||
|
@ -278,15 +239,9 @@ const local = new Whisper.Message({
|
||||||
|
|
||||||
const View = Whisper.VerifiedChangeView;
|
const View = Whisper.VerifiedChangeView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: fromPrimary }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: local }} />
|
||||||
options={{ model: fromPrimary }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: local }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Marking as not verified
|
#### Marking as not verified
|
||||||
|
@ -306,15 +261,9 @@ const local = new Whisper.Message({
|
||||||
|
|
||||||
const View = Whisper.VerifiedChangeView;
|
const View = Whisper.VerifiedChangeView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: fromPrimary }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: local }} />
|
||||||
options={{ model: fromPrimary }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: local }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Group update
|
#### Group update
|
||||||
|
@ -324,29 +273,21 @@ const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
sent_at: Date.now() - 200000,
|
sent_at: Date.now() - 200000,
|
||||||
group_update: {
|
group_update: {
|
||||||
joined: [
|
joined: ['+12025550007', '+12025550008', '+12025550009'],
|
||||||
'+12025550007',
|
|
||||||
'+12025550008',
|
|
||||||
'+12025550009',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### End session
|
#### End session
|
||||||
|
@ -357,22 +298,18 @@ const outgoing = new Whisper.Message({
|
||||||
sent_at: Date.now() - 200000,
|
sent_at: Date.now() - 200000,
|
||||||
flags: textsecure.protobuf.DataMessage.Flags.END_SESSION,
|
flags: textsecure.protobuf.DataMessage.Flags.END_SESSION,
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### With an attachment
|
### With an attachment
|
||||||
|
@ -384,27 +321,25 @@ const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
body: 'I am pretty confused about Pi.',
|
body: 'I am pretty confused about Pi.',
|
||||||
sent_at: Date.now() - 18000000,
|
sent_at: Date.now() - 18000000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.gif,
|
data: util.gif,
|
||||||
fileName: 'pi.gif',
|
fileName: 'pi.gif',
|
||||||
contentType: 'image/gif',
|
contentType: 'image/gif',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Image
|
#### Image
|
||||||
|
@ -413,27 +348,25 @@ const View = Whisper.MessageView;
|
||||||
const outgoing = new Whisper.Message({
|
const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
sent_at: Date.now() - 18000000,
|
sent_at: Date.now() - 18000000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.gif,
|
data: util.gif,
|
||||||
fileName: 'pi.gif',
|
fileName: 'pi.gif',
|
||||||
contentType: 'image/gif',
|
contentType: 'image/gif',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Image with portrait aspect ratio
|
#### Image with portrait aspect ratio
|
||||||
|
@ -442,30 +375,27 @@ const View = Whisper.MessageView;
|
||||||
const outgoing = new Whisper.Message({
|
const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
sent_at: Date.now() - 18000000,
|
sent_at: Date.now() - 18000000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.portraitYellow,
|
data: util.portraitYellow,
|
||||||
fileName: 'portraitYellow.png',
|
fileName: 'portraitYellow.png',
|
||||||
contentType: 'image/png',
|
contentType: 'image/png',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
#### Image with portrait aspect ratio and caption
|
#### Image with portrait aspect ratio and caption
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
|
@ -473,27 +403,25 @@ const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
body: 'This is an odd yellow bar. Cool, huh?',
|
body: 'This is an odd yellow bar. Cool, huh?',
|
||||||
sent_at: Date.now() - 18000000,
|
sent_at: Date.now() - 18000000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.portraitYellow,
|
data: util.portraitYellow,
|
||||||
fileName: 'portraitYellow.png',
|
fileName: 'portraitYellow.png',
|
||||||
contentType: 'image/png',
|
contentType: 'image/png',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Image with landscape aspect ratio
|
#### Image with landscape aspect ratio
|
||||||
|
@ -502,27 +430,25 @@ const View = Whisper.MessageView;
|
||||||
const outgoing = new Whisper.Message({
|
const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
sent_at: Date.now() - 18000000,
|
sent_at: Date.now() - 18000000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.landscapePurple,
|
data: util.landscapePurple,
|
||||||
fileName: 'landscapePurple.jpg',
|
fileName: 'landscapePurple.jpg',
|
||||||
contentType: 'image/jpeg',
|
contentType: 'image/jpeg',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Image with landscape aspect ratio and caption
|
#### Image with landscape aspect ratio and caption
|
||||||
|
@ -532,27 +458,25 @@ const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
body: "An interesting horizontal bar. It's art.",
|
body: "An interesting horizontal bar. It's art.",
|
||||||
sent_at: Date.now() - 18000000,
|
sent_at: Date.now() - 18000000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.landscapePurple,
|
data: util.landscapePurple,
|
||||||
fileName: 'landscapePurple.jpg',
|
fileName: 'landscapePurple.jpg',
|
||||||
contentType: 'image/jpeg',
|
contentType: 'image/jpeg',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Video with caption
|
#### Video with caption
|
||||||
|
@ -562,27 +486,25 @@ const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
body: "Beautiful, isn't it?",
|
body: "Beautiful, isn't it?",
|
||||||
sent_at: Date.now() - 10000,
|
sent_at: Date.now() - 10000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.mp4,
|
data: util.mp4,
|
||||||
fileName: 'freezing_bubble.mp4',
|
fileName: 'freezing_bubble.mp4',
|
||||||
contentType: 'video/mp4',
|
contentType: 'video/mp4',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Video
|
#### Video
|
||||||
|
@ -591,27 +513,25 @@ const View = Whisper.MessageView;
|
||||||
const outgoing = new Whisper.Message({
|
const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
sent_at: Date.now() - 10000,
|
sent_at: Date.now() - 10000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.mp4,
|
data: util.mp4,
|
||||||
fileName: 'freezing_bubble.mp4',
|
fileName: 'freezing_bubble.mp4',
|
||||||
contentType: 'video/mp4',
|
contentType: 'video/mp4',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Audio with caption
|
#### Audio with caption
|
||||||
|
@ -621,27 +541,25 @@ const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
body: 'This is a nice song',
|
body: 'This is a nice song',
|
||||||
sent_at: Date.now() - 15000,
|
sent_at: Date.now() - 15000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.mp3,
|
data: util.mp3,
|
||||||
fileName: 'agnus_dei.mp3',
|
fileName: 'agnus_dei.mp3',
|
||||||
contentType: 'audio/mp3',
|
contentType: 'audio/mp3',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Audio
|
#### Audio
|
||||||
|
@ -650,27 +568,25 @@ const View = Whisper.MessageView;
|
||||||
const outgoing = new Whisper.Message({
|
const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
sent_at: Date.now() - 15000,
|
sent_at: Date.now() - 15000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.mp3,
|
data: util.mp3,
|
||||||
fileName: 'agnus_dei.mp3',
|
fileName: 'agnus_dei.mp3',
|
||||||
contentType: 'audio/mp3',
|
contentType: 'audio/mp3',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Voice message
|
#### Voice message
|
||||||
|
@ -679,28 +595,26 @@ const View = Whisper.MessageView;
|
||||||
const outgoing = new Whisper.Message({
|
const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
sent_at: Date.now() - 15000,
|
sent_at: Date.now() - 15000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
flags: textsecure.protobuf.AttachmentPointer.Flags.VOICE_MESSAGE,
|
flags: textsecure.protobuf.AttachmentPointer.Flags.VOICE_MESSAGE,
|
||||||
data: util.mp3,
|
data: util.mp3,
|
||||||
fileName: 'agnus_dei.mp3',
|
fileName: 'agnus_dei.mp3',
|
||||||
contentType: 'audio/mp3',
|
contentType: 'audio/mp3',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Other file type with caption
|
#### Other file type with caption
|
||||||
|
@ -710,27 +624,25 @@ const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
body: 'My manifesto is now complete!',
|
body: 'My manifesto is now complete!',
|
||||||
sent_at: Date.now() - 15000,
|
sent_at: Date.now() - 15000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.txt,
|
data: util.txt,
|
||||||
fileName: 'lorum_ipsum.txt',
|
fileName: 'lorum_ipsum.txt',
|
||||||
contentType: 'text/plain',
|
contentType: 'text/plain',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Other file type
|
#### Other file type
|
||||||
|
@ -739,25 +651,23 @@ const View = Whisper.MessageView;
|
||||||
const outgoing = new Whisper.Message({
|
const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
sent_at: Date.now() - 15000,
|
sent_at: Date.now() - 15000,
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.txt,
|
data: util.txt,
|
||||||
fileName: 'lorum_ipsum.txt',
|
fileName: 'lorum_ipsum.txt',
|
||||||
contentType: 'text/plain',
|
contentType: 'text/plain',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550003',
|
source: '+12025550003',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
### With a quotation, text-only replies
|
### With a quotation, text-only replies
|
||||||
|
|
||||||
#### Plain text
|
#### Plain text
|
||||||
|
@ -14,24 +13,20 @@ const outgoing = new Whisper.Message({
|
||||||
id: Date.now() - 1000,
|
id: Date.now() - 1000,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### With emoji
|
#### With emoji
|
||||||
|
@ -47,24 +42,20 @@ const outgoing = new Whisper.Message({
|
||||||
id: Date.now() - 1000,
|
id: Date.now() - 1000,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Replies to you or yourself
|
#### Replies to you or yourself
|
||||||
|
@ -80,24 +71,20 @@ const outgoing = new Whisper.Message({
|
||||||
id: Date.now() - 1000,
|
id: Date.now() - 1000,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: util.ourNumber,
|
author: util.ourNumber,
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### In a group conversation
|
#### In a group conversation
|
||||||
|
@ -113,24 +100,20 @@ const outgoing = new Whisper.Message({
|
||||||
id: Date.now() - 1000,
|
id: Date.now() - 1000,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550007',
|
source: '+12025550007',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550002',
|
author: '+12025550002',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme} type="group">
|
<util.ConversationContext theme={util.theme} type="group">
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### A lot of text in quotation
|
#### A lot of text in quotation
|
||||||
|
@ -150,24 +133,20 @@ const outgoing = new Whisper.Message({
|
||||||
id: Date.now() - 1000,
|
id: Date.now() - 1000,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### A lot of text in quotation, with icon
|
#### A lot of text in quotation, with icon
|
||||||
|
@ -193,24 +172,20 @@ const outgoing = new Whisper.Message({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### A lot of text in quotation, with image
|
#### A lot of text in quotation, with image
|
||||||
|
@ -242,28 +217,24 @@ const outgoing = new Whisper.Message({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
outgoing.quoteThumbnail = thumbnail;
|
outgoing.quoteThumbnail = thumbnail;
|
||||||
incoming.quoteThumbnail = thumbnail;
|
incoming.quoteThumbnail = thumbnail;
|
||||||
|
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Image with caption
|
#### Image with caption
|
||||||
|
@ -292,28 +263,24 @@ const outgoing = new Whisper.Message({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
outgoing.quoteThumbnail = thumbnail;
|
outgoing.quoteThumbnail = thumbnail;
|
||||||
incoming.quoteThumbnail = thumbnail;
|
incoming.quoteThumbnail = thumbnail;
|
||||||
|
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Image
|
#### Image
|
||||||
|
@ -325,7 +292,7 @@ const thumbnail = {
|
||||||
|
|
||||||
const outgoing = new Whisper.Message({
|
const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
body: "Yeah, pi. Tough to wrap your head around.",
|
body: 'Yeah, pi. Tough to wrap your head around.',
|
||||||
sent_at: Date.now() - 18000000,
|
sent_at: Date.now() - 18000000,
|
||||||
quote: {
|
quote: {
|
||||||
author: '+12025550011',
|
author: '+12025550011',
|
||||||
|
@ -341,28 +308,24 @@ const outgoing = new Whisper.Message({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
outgoing.quoteThumbnail = thumbnail;
|
outgoing.quoteThumbnail = thumbnail;
|
||||||
incoming.quoteThumbnail = thumbnail;
|
incoming.quoteThumbnail = thumbnail;
|
||||||
|
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Image with no thumbnail
|
#### Image with no thumbnail
|
||||||
|
@ -370,7 +333,7 @@ const View = Whisper.MessageView;
|
||||||
```jsx
|
```jsx
|
||||||
const outgoing = new Whisper.Message({
|
const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
body: "Yeah, pi. Tough to wrap your head around.",
|
body: 'Yeah, pi. Tough to wrap your head around.',
|
||||||
sent_at: Date.now() - 18000000,
|
sent_at: Date.now() - 18000000,
|
||||||
quote: {
|
quote: {
|
||||||
author: '+12025550011',
|
author: '+12025550011',
|
||||||
|
@ -383,25 +346,21 @@ const outgoing = new Whisper.Message({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Video with caption
|
#### Video with caption
|
||||||
|
@ -413,7 +372,7 @@ const thumbnail = {
|
||||||
|
|
||||||
const outgoing = new Whisper.Message({
|
const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
body: "Sweet the way the video sneaks up on you!",
|
body: 'Sweet the way the video sneaks up on you!',
|
||||||
sent_at: Date.now() - 18000000,
|
sent_at: Date.now() - 18000000,
|
||||||
quote: {
|
quote: {
|
||||||
author: '+12025550011',
|
author: '+12025550011',
|
||||||
|
@ -430,28 +389,24 @@ const outgoing = new Whisper.Message({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
outgoing.quoteThumbnail = thumbnail;
|
outgoing.quoteThumbnail = thumbnail;
|
||||||
incoming.quoteThumbnail = thumbnail;
|
incoming.quoteThumbnail = thumbnail;
|
||||||
|
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Video
|
#### Video
|
||||||
|
@ -463,7 +418,7 @@ const thumbnail = {
|
||||||
|
|
||||||
const outgoing = new Whisper.Message({
|
const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
body: "Awesome!",
|
body: 'Awesome!',
|
||||||
sent_at: Date.now() - 18000000,
|
sent_at: Date.now() - 18000000,
|
||||||
quote: {
|
quote: {
|
||||||
author: '+12025550011',
|
author: '+12025550011',
|
||||||
|
@ -475,33 +430,29 @@ const outgoing = new Whisper.Message({
|
||||||
thumbnail: {
|
thumbnail: {
|
||||||
contentType: 'image/gif',
|
contentType: 'image/gif',
|
||||||
data: util.gif,
|
data: util.gif,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
outgoing.quoteThumbnail = thumbnail;
|
outgoing.quoteThumbnail = thumbnail;
|
||||||
incoming.quoteThumbnail = thumbnail;
|
incoming.quoteThumbnail = thumbnail;
|
||||||
|
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Video with no thumbnail
|
#### Video with no thumbnail
|
||||||
|
@ -509,7 +460,7 @@ const View = Whisper.MessageView;
|
||||||
```jsx
|
```jsx
|
||||||
const outgoing = new Whisper.Message({
|
const outgoing = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
body: "Awesome!",
|
body: 'Awesome!',
|
||||||
sent_at: Date.now() - 18000000,
|
sent_at: Date.now() - 18000000,
|
||||||
quote: {
|
quote: {
|
||||||
author: '+12025550011',
|
author: '+12025550011',
|
||||||
|
@ -522,25 +473,21 @@ const outgoing = new Whisper.Message({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Audio with caption
|
#### Audio with caption
|
||||||
|
@ -562,24 +509,20 @@ const outgoing = new Whisper.Message({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Audio
|
#### Audio
|
||||||
|
@ -600,24 +543,20 @@ const outgoing = new Whisper.Message({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Voice message
|
#### Voice message
|
||||||
|
@ -640,24 +579,20 @@ const outgoing = new Whisper.Message({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Other file type with caption
|
#### Other file type with caption
|
||||||
|
@ -679,24 +614,20 @@ const outgoing = new Whisper.Message({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Other file type
|
#### Other file type
|
||||||
|
@ -717,24 +648,20 @@ const outgoing = new Whisper.Message({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### With a quotation, including attachment
|
### With a quotation, including attachment
|
||||||
|
@ -751,30 +678,28 @@ const outgoing = new Whisper.Message({
|
||||||
author: '+12025550011',
|
author: '+12025550011',
|
||||||
id: Date.now() - 1000,
|
id: Date.now() - 1000,
|
||||||
},
|
},
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.gif,
|
data: util.gif,
|
||||||
fileName: 'pi.gif',
|
fileName: 'pi.gif',
|
||||||
contentType: 'image/gif',
|
contentType: 'image/gif',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Quote, image attachment
|
#### Quote, image attachment
|
||||||
|
@ -788,30 +713,28 @@ const outgoing = new Whisper.Message({
|
||||||
author: '+12025550011',
|
author: '+12025550011',
|
||||||
id: Date.now() - 1000,
|
id: Date.now() - 1000,
|
||||||
},
|
},
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.gif,
|
data: util.gif,
|
||||||
fileName: 'pi.gif',
|
fileName: 'pi.gif',
|
||||||
contentType: 'image/gif',
|
contentType: 'image/gif',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Quote, portrait image attachment
|
#### Quote, portrait image attachment
|
||||||
|
@ -825,33 +748,30 @@ const outgoing = new Whisper.Message({
|
||||||
author: '+12025550011',
|
author: '+12025550011',
|
||||||
id: Date.now() - 1000,
|
id: Date.now() - 1000,
|
||||||
},
|
},
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.portraitYellow,
|
data: util.portraitYellow,
|
||||||
fileName: 'pi.gif',
|
fileName: 'pi.gif',
|
||||||
contentType: 'image/gif',
|
contentType: 'image/gif',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
#### Quote, video attachment
|
#### Quote, video attachment
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
|
@ -863,30 +783,28 @@ const outgoing = new Whisper.Message({
|
||||||
author: '+12025550011',
|
author: '+12025550011',
|
||||||
id: Date.now() - 1000,
|
id: Date.now() - 1000,
|
||||||
},
|
},
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.mp4,
|
data: util.mp4,
|
||||||
fileName: 'freezing_bubble.mp4',
|
fileName: 'freezing_bubble.mp4',
|
||||||
contentType: 'video/mp4',
|
contentType: 'video/mp4',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Quote, audio attachment
|
#### Quote, audio attachment
|
||||||
|
@ -900,30 +818,28 @@ const outgoing = new Whisper.Message({
|
||||||
author: '+12025550011',
|
author: '+12025550011',
|
||||||
id: Date.now() - 1000,
|
id: Date.now() - 1000,
|
||||||
},
|
},
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.mp3,
|
data: util.mp3,
|
||||||
fileName: 'agnus_dei.mp3',
|
fileName: 'agnus_dei.mp3',
|
||||||
contentType: 'audio/mp3',
|
contentType: 'audio/mp3',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Quote, file attachment
|
#### Quote, file attachment
|
||||||
|
@ -937,31 +853,28 @@ const outgoing = new Whisper.Message({
|
||||||
author: '+12025550011',
|
author: '+12025550011',
|
||||||
id: Date.now() - 1000,
|
id: Date.now() - 1000,
|
||||||
},
|
},
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: util.txt,
|
data: util.txt,
|
||||||
fileName: 'lorum_ipsum.txt',
|
fileName: 'lorum_ipsum.txt',
|
||||||
contentType: 'text/plain',
|
contentType: 'text/plain',
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
|
})
|
||||||
}));
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Quote, but no message
|
#### Quote, but no message
|
||||||
|
@ -976,24 +889,20 @@ const outgoing = new Whisper.Message({
|
||||||
id: Date.now() - 1000,
|
id: Date.now() - 1000,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const incoming = new Whisper.Message(Object.assign({}, outgoing.attributes, {
|
const incoming = new Whisper.Message(
|
||||||
|
Object.assign({}, outgoing.attributes, {
|
||||||
source: '+12025550011',
|
source: '+12025550011',
|
||||||
type: 'incoming',
|
type: 'incoming',
|
||||||
quote: Object.assign({}, outgoing.attributes.quote, {
|
quote: Object.assign({}, outgoing.attributes.quote, {
|
||||||
author: '+12025550005',
|
author: '+12025550005',
|
||||||
}),
|
}),
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={{ model: incoming }} />
|
||||||
View={View}
|
<util.BackboneWrapper View={View} options={{ model: outgoing }} />
|
||||||
options={{ model: incoming }}
|
</util.ConversationContext>;
|
||||||
/>
|
|
||||||
<util.BackboneWrapper
|
|
||||||
View={View}
|
|
||||||
options={{ model: outgoing }}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### In bottom bar
|
### In bottom bar
|
||||||
|
@ -1027,10 +936,12 @@ const View = Whisper.MessageView;
|
||||||
authorProfileName="Mr. Blue"
|
authorProfileName="Mr. Blue"
|
||||||
id={Date.now() - 1000}
|
id={Date.now() - 1000}
|
||||||
i18n={window.i18n}
|
i18n={window.i18n}
|
||||||
attachments={[{
|
attachments={[
|
||||||
|
{
|
||||||
contentType: 'image/jpeg',
|
contentType: 'image/jpeg',
|
||||||
fileName: 'llama.jpg',
|
fileName: 'llama.jpg',
|
||||||
}]}
|
},
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1048,13 +959,15 @@ const View = Whisper.MessageView;
|
||||||
authorProfileName="Mr. Blue"
|
authorProfileName="Mr. Blue"
|
||||||
id={Date.now() - 1000}
|
id={Date.now() - 1000}
|
||||||
i18n={window.i18n}
|
i18n={window.i18n}
|
||||||
attachments={[{
|
attachments={[
|
||||||
|
{
|
||||||
contentType: 'image/gif',
|
contentType: 'image/gif',
|
||||||
fileName: 'llama.gif',
|
fileName: 'llama.gif',
|
||||||
thumbnail: {
|
thumbnail: {
|
||||||
objectUrl: util.gifObjectUrl
|
objectUrl: util.gifObjectUrl,
|
||||||
},
|
},
|
||||||
}]}
|
},
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1091,10 +1004,12 @@ const View = Whisper.MessageView;
|
||||||
id={Date.now() - 1000}
|
id={Date.now() - 1000}
|
||||||
onClose={() => console.log('Close was clicked!')}
|
onClose={() => console.log('Close was clicked!')}
|
||||||
i18n={window.i18n}
|
i18n={window.i18n}
|
||||||
attachments={[{
|
attachments={[
|
||||||
|
{
|
||||||
contentType: 'image/jpeg',
|
contentType: 'image/jpeg',
|
||||||
fileName: 'llama.jpg',
|
fileName: 'llama.jpg',
|
||||||
}]}
|
},
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1113,13 +1028,15 @@ const View = Whisper.MessageView;
|
||||||
id={Date.now() - 1000}
|
id={Date.now() - 1000}
|
||||||
onClose={() => console.log('Close was clicked!')}
|
onClose={() => console.log('Close was clicked!')}
|
||||||
i18n={window.i18n}
|
i18n={window.i18n}
|
||||||
attachments={[{
|
attachments={[
|
||||||
|
{
|
||||||
contentType: 'image/gif',
|
contentType: 'image/gif',
|
||||||
fileName: 'llama.gif',
|
fileName: 'llama.gif',
|
||||||
thumbnail: {
|
thumbnail: {
|
||||||
objectUrl: util.gifObjectUrl
|
objectUrl: util.gifObjectUrl,
|
||||||
},
|
},
|
||||||
}]}
|
},
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
```js
|
```js
|
||||||
<div style={{ position: "relative", width: "100%", height: 300 }}>
|
<div style={{ position: 'relative', width: '100%', height: 300 }}>
|
||||||
<EmptyState label="You have no attachments with media" />
|
<EmptyState label="You have no attachments with media" />
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
```js
|
```js
|
||||||
<div style={{ position: "relative", width: "100%", height: 500 }}>
|
<div style={{ position: 'relative', width: '100%', height: 500 }}>
|
||||||
<EmptyState label="You have no documents with media" />
|
<EmptyState label="You have no documents with media" />
|
||||||
</div>
|
</div>
|
||||||
```
|
```
|
||||||
|
|
|
@ -18,20 +18,26 @@ const MONTH_MS = 30 * DAY_MS;
|
||||||
const YEAR_MS = 12 * MONTH_MS;
|
const YEAR_MS = 12 * MONTH_MS;
|
||||||
const tokens = ['foo', 'bar', 'baz', 'qux', 'quux'];
|
const tokens = ['foo', 'bar', 'baz', 'qux', 'quux'];
|
||||||
const fileExtensions = ['docx', 'pdf', 'txt', 'mp3', 'wmv', 'tiff'];
|
const fileExtensions = ['docx', 'pdf', 'txt', 'mp3', 'wmv', 'tiff'];
|
||||||
const createRandomMessage = ({startTime, timeWindow} = {}) => (props) => {
|
const createRandomMessage = ({ startTime, timeWindow } = {}) => props => {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const fileName =
|
const fileName = `${_.sample(tokens)}${_.sample(tokens)}.${_.sample(
|
||||||
`${_.sample(tokens)}${_.sample(tokens)}.${_.sample(fileExtensions)}`;
|
fileExtensions
|
||||||
|
)}`;
|
||||||
return {
|
return {
|
||||||
id: _.random(now).toString(),
|
id: _.random(now).toString(),
|
||||||
received_at: _.random(startTime, startTime + timeWindow),
|
received_at: _.random(startTime, startTime + timeWindow),
|
||||||
attachments: [{
|
attachments: [
|
||||||
|
{
|
||||||
data: null,
|
data: null,
|
||||||
fileName,
|
fileName,
|
||||||
size: _.random(1000, 1000 * 1000 * 50),
|
size: _.random(1000, 1000 * 1000 * 50),
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
|
|
||||||
objectURL: `https://placekitten.com/${_.random(50, 150)}/${_.random(50, 150)}`,
|
objectURL: `https://placekitten.com/${_.random(50, 150)}/${_.random(
|
||||||
|
50,
|
||||||
|
150
|
||||||
|
)}`,
|
||||||
...props,
|
...props,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -39,7 +45,6 @@ const createRandomMessage = ({startTime, timeWindow} = {}) => (props) => {
|
||||||
const createRandomMessages = ({ startTime, timeWindow }) =>
|
const createRandomMessages = ({ startTime, timeWindow }) =>
|
||||||
_.range(_.random(5, 10)).map(createRandomMessage({ startTime, timeWindow }));
|
_.range(_.random(5, 10)).map(createRandomMessage({ startTime, timeWindow }));
|
||||||
|
|
||||||
|
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
const messages = _.sortBy(
|
const messages = _.sortBy(
|
||||||
[
|
[
|
||||||
|
@ -67,9 +72,5 @@ const messages = _.sortBy(
|
||||||
message => -message.received_at
|
message => -message.received_at
|
||||||
);
|
);
|
||||||
|
|
||||||
<MediaGallery
|
<MediaGallery i18n={window.i18n} media={messages} documents={messages} />;
|
||||||
i18n={window.i18n}
|
|
||||||
media={messages}
|
|
||||||
documents={messages}
|
|
||||||
/>
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -6,15 +6,12 @@ const model = new Whisper.Message({
|
||||||
type: 'outgoing',
|
type: 'outgoing',
|
||||||
body: 'text',
|
body: 'text',
|
||||||
sent_at: Date.now() - 5000,
|
sent_at: Date.now() - 5000,
|
||||||
})
|
});
|
||||||
const View = Whisper.MessageView;
|
const View = Whisper.MessageView;
|
||||||
const options = {
|
const options = {
|
||||||
model,
|
model,
|
||||||
};
|
};
|
||||||
<util.ConversationContext theme={util.theme}>
|
<util.ConversationContext theme={util.theme}>
|
||||||
<util.BackboneWrapper
|
<util.BackboneWrapper View={View} options={options} />
|
||||||
View={View}
|
</util.ConversationContext>;
|
||||||
options={options}
|
|
||||||
/>
|
|
||||||
</util.ConversationContext>
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
The simplest example of using the `<ConversationContext />` component:
|
The simplest example of using the `<ConversationContext />` component:
|
||||||
|
|
||||||
```jsx
|
```jsx
|
||||||
|
|
Loading…
Reference in a new issue