* refactor: pass inline media upload data to useRoom
* feat: render inline media
* fix: don't rescind inline media file offers
* refactor: send file offer metadata object
* fix: enable re-seeding of inline media files
* feat: show loading indicator for inline media
* feat: rescind any evicted inline media
* feat: display media rendering failure message
* feat: prevent user from uploading file if message is sending
* feat: [#21] stand up file sharing controls UI
* feat: [#21] implement basic file transfer
* feat: [#21] save transferred file
* feat: [#21] transfer file via WebTorrent
* fix: use external streamsaver assets
* feat: [#21] initiate download by receiver click
* fix: enable re-downloading of shared files
* feat: [#21] implement sharing of multiple files
* chore: enable offline development
* feat: cache torrents in IndexedDB
* feat: show alert when download is aborted
* feat: [#21] clean up torrent data when principal offerer rescinds it
* feat: clean up cached torrents on page unload
* feat: show file transfer progress
* fix: download files sequentially
* feat: clean up file transfers when leaving the room
* feat: clean up broken downloads upon leaving the page
* fix: allow download animation to complete
* feat: show tooltip for download button
* feat: make file transfers work in browser private modes
* feat: disable file share controls while creating offer
* refactor: nest ChatTranscript
* feat: set up video controls
* feat: show self video
* feat: show peer video
* feat: improve audio/video controls display
* feat: flip self video
* feat: improve device selection labels
* feat: [#6] show notification when message is received
* feat: [#6] add setting for enabling/disabling notifications
* refactor: [#6] decouple PeerNameDisplay from funAnimalName
* feat: [#6] disable notifications setting when notifications are unavailable
* feat: [#7] Play a sound on new message
* fix: [#7] Since this mock is a no-op, I think we can omit the argument to mockImplementation
Co-authored-by: Jeremy Kahn <jeremyckahn@gmail.com>
* fix: [#7] lazy initialization of this state
Co-authored-by: Jeremy Kahn <jeremyckahn@gmail.com>
* fix: [#7] More accurate error message
Co-authored-by: Jeremy Kahn <jeremyckahn@gmail.com>
* fix: [#7] Replace then with await
* [closes#24] Settings UI (#26)
* feat: [#24] wire up settings page
* feat: [#24] stand up settings UI
* feat: [#24] implement storage deletion
* feat: [#24] confirm deletion of settings data
* feat: [#7] Add play sound switch in settings
* feat: [#7] avoid typescript warning
Co-authored-by: Jeremy Kahn <jeremyckahn@gmail.com>
* feat: [#7] more straighforward wording
Co-authored-by: Jeremy Kahn <jeremyckahn@gmail.com>
* feat: [#7] remove useless usestate
* feat: [#7] avoid new settings to be undefined in persisted storage
* feat: [#7] creating a chat section in settings
Co-authored-by: Jeremy Kahn <jeremyckahn@gmail.com>