Skip to content

Commit

Permalink
feat(calls): changes to calling, screen sharing, group calls WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Drew Ewing committed May 5, 2022
1 parent ad2d2db commit 505234e
Show file tree
Hide file tree
Showing 82 changed files with 2,141 additions and 1,434 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,8 @@ sw.*
# Scratchpad files for testing stuff
scratchpad.ts
scratchpad.js

# Browser profiles for debugging
.vscode/firefox/
.vscode/pwa-msedge/
.vscode/chrome/
74 changes: 74 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "pwa-msedge",
"name": "edge: profile-1",
"request": "launch",
"url": "http://localhost:3000/?p1",
"userDataDir": "${workspaceFolder}/.vscode/pwa-msedge/profile-1"
},
{
"type": "pwa-msedge",
"name": "edge: profile-2",
"request": "launch",
"url": "http://localhost:3000/?p2",
"userDataDir": "${workspaceFolder}/.vscode/pwa-msedge/profile-2"
},
{
"type": "pwa-msedge",
"name": "edge: profile-3",
"request": "launch",
"url": "http://localhost:3000/?p3",
"userDataDir": "${workspaceFolder}/.vscode/pwa-msedge/profile-3"
},
{
"type": "vscode-edge-devtools.debug",
"name": "edge: devtools",
"request": "attach",
"url": "http://localhost:3000/"
},
{
"name": "browser: firefox",
"type": "firefox",
"request": "launch",
"url": "http://localhost:3000",
"reAttach": true,
"profile": "debug",
"keepProfileChanges": true,
"profileDir": "${workspaceRoot}/.vscode/firefox",
"webRoot": "${workspaceFolder}",
"pathMappings": [
{
"url": "webpack:///",
"path": "${webRoot}/"
}
]
},
{
"type": "node",
"request": "launch",
"name": "server: nuxi",
"args": ["dev"],
"osx": {
"program": "${workspaceFolder}/node_modules/.bin/nuxi"
},
"linux": {
"program": "${workspaceFolder}/node_modules/.bin/nuxi"
},
"windows": {
"program": "${workspaceFolder}/node_modules/nuxt/bin/nuxi.mjs"
}
}
],
"compounds": [
{
"name": "fullstack: nuxi",
"configurations": ["server: nuxi", "browser: firefox"]
},
{
"name": "edge: profile-1 w/ devtools",
"configurations": ["edge: profile-1", "edge: devtools"]
}
]
}
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"cSpell.words": ["Dexie"]
"cSpell.words": ["Dexie", "minisearch"]
}
1 change: 1 addition & 0 deletions __mocks__/it-pipe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export function pipe() {}
11 changes: 2 additions & 9 deletions components/ui/Global/Global.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,8 @@
:set-close-timeout="5000"
/>
</UiModal>
<UiModal
v-if="this.$store.state.friends.all.some((friend) => friend.peerId === this.$store.state.webrtc.incomingCall)"
nopad
>
<MediaIncomingCall
:user="this.$store.state.friends.all.find((friend) => friend.peerId === this.$store.state.webrtc.incomingCall)"
:accept-call="acceptCall"
:deny-call="denyCall"
/>
<UiModal v-if="webrtc.incomingCall" nopad>
<MediaIncomingCall :accept-call="acceptCall" :deny-call="denyCall" />
</UiModal>
<UiModal
v-if="ui.modals.marketplace"
Expand Down
56 changes: 37 additions & 19 deletions components/ui/Global/Global.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { TrackKind } from '~/libraries/WebRTC/types'
import { ModalWindows } from '~/store/ui/types'
import { Item } from '~/libraries/Files/abstracts/Item.abstract'
import { Peer2Peer } from '~/libraries/WebRTC/Libp2p'
import { $WebRTC } from '~/libraries/WebRTC/WebRTC'
import { Friend } from '~/types/ui/friends'
const p2p = Peer2Peer.getInstance()
declare module 'vue/types/vue' {
interface Vue {
Expand All @@ -16,7 +20,7 @@ declare module 'vue/types/vue' {
export default Vue.extend({
name: 'Global',
computed: {
...mapState(['ui', 'media', 'webrtc']),
...mapState(['ui', 'media', 'webrtc', 'conversation']),
ModalWindows: () => ModalWindows,
},
mounted() {
Expand Down Expand Up @@ -68,30 +72,49 @@ export default Vue.extend({
* @example
*/
async acceptCall(kinds: TrackKind[]) {
if (this.webrtc.activeCall) {
this.hangUp()
}
const identifier = this.webrtc.incomingCall
const call = this.$WebRTC.getPeer(identifier)
this.$store.commit('webrtc/setStreamMuted', {
peerId: p2p.id,
audio: true,
video: true,
screen: true,
})
const { callId, peerId } = this.webrtc.incomingCall
const call = $WebRTC.getCall(callId)
if (!call) return
if (call) {
try {
await call.createLocalTracks(kinds)
await call.answer()
await call.answer(peerId)
this.$store.commit(
'webrtc/setActiveCall',
{ callId, peerId },
{ root: true },
)
this.$store.commit('webrtc/setIncomingCall', undefined, {
root: true,
})
} catch (error) {
if (error instanceof Error) {
this.$toast.error(this.$t(error.message) as string)
}
}
}
const callingPath = `/chat/direct/${identifier}`
const redirectId =
this.conversation.type === 'group'
? `groups/${callId}`
: `direct/${
this.$store.state.friends.all.find(
(f: Friend) => f.peerId === peerId,
)?.address || 'error'
}`
const callingPath = `/chat/${redirectId}`
if (this.$route.path !== callingPath) {
this.$router.push(callingPath)
}
if (this.ui.showSettings) {
this.$store.commit('ui/toggleSettings', { show: false })
}
Expand All @@ -102,11 +125,8 @@ export default Vue.extend({
* @example
*/
denyCall() {
const identifier = this.webrtc.incomingCall
const call = this.$WebRTC.getPeer(identifier)
if (call) call.deny()
this.$store.commit('webrtc/setIncomingCall', undefined)
this.$store.commit('ui/fullscreen', false)
this.$store.dispatch('webrtc/denyCall')
},
/**
Expand All @@ -115,11 +135,9 @@ export default Vue.extend({
* @example
*/
hangUp() {
if (!this.webrtc.activeCall) return
const call = this.$WebRTC.getPeer(this.webrtc.activeCall)
if (call) call.hangUp()
this.$store.dispatch('webrtc/hangUp')
this.$store.commit('webrtc/setIncomingCall', undefined, { root: true })
this.$store.commit('ui/fullscreen', false)
this.$store.dispatch('webrtc/hangUp')
},
/**
* @method share
Expand Down
50 changes: 15 additions & 35 deletions components/views/chat/chatbar/Chatbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Vue, { PropType } from 'vue'
import { mapState, mapGetters } from 'vuex'
import { throttle } from 'lodash'
import { TerminalIcon } from 'satellite-lucide-icons'
import PeerId from 'peer-id'
import Upload from '../../files/upload/Upload.vue'
import FilePreview from '../../files/upload/filePreview/FilePreview.vue'
Expand All @@ -17,8 +16,8 @@ import {
PropCommonEnum,
} from '~/libraries/Enums/enums'
import { Config } from '~/config'
import { Peer2Peer } from '~/libraries/WebRTC/Libp2p'
import { UploadDropItemType } from '~/types/files/file'
import { Group } from '~/types/messaging'
declare module 'vue/types/vue' {
interface Vue {
Expand All @@ -43,7 +42,7 @@ export default Vue.extend({
},
props: {
recipient: {
type: Object as PropType<Friend>,
type: Object as PropType<Friend | Group>,
default: () => {},
},
},
Expand All @@ -56,10 +55,10 @@ export default Vue.extend({
}
},
computed: {
...mapState(['ui', 'friends', 'webrtc', 'chat', 'textile']),
...mapGetters('chat', ['getFiles']),
...mapState(['ui', 'friends', 'webrtc', 'chat', 'textile', 'conversation']),
activeFriend() {
return this.$Hounddog.getActiveFriend(this.friends)
return this.conversation?.participants?.[0]
},
/**
* Computes the amount of characters left
Expand Down Expand Up @@ -153,6 +152,9 @@ export default Vue.extend({
this.$data.recipientTyping =
activeFriend.typingState === PropCommonEnum.TYPING
},
},
'conversation.participants': {
handler() {},
deep: true,
},
'recipient.address': {
Expand Down Expand Up @@ -205,29 +207,7 @@ export default Vue.extend({
typingNotifHandler(
state: PropCommonEnum.TYPING | PropCommonEnum.NOT_TYPING,
) {
const activeFriend = this.$Hounddog.getActiveFriend(this.friends)
if (activeFriend) {
try {
const p2p = Peer2Peer.getInstance()
if (!activeFriend.peerId) return
p2p.sendMessage(
{
type: 'TYPING_STATE',
payload: { state: 'TYPING' },
sentAt: Date.now(),
},
PeerId.createFromB58String(activeFriend.peerId),
)
// const activePeer = this.$WebRTC.getPeer(activeFriend.address)
// activePeer?.send('TYPING_STATE', { state })
} catch (error: any) {
this.$Logger.log('cannot send after peer is destroyed', 'ERROR', {
error,
})
}
}
// TODO use conversation participants
},
/**
* @method throttleTyping
Expand Down Expand Up @@ -299,25 +279,25 @@ export default Vue.extend({
}
if (
this.ui.replyChatbarContent.from &&
!RegExp(this.$Config.regex.uuidv4).test(this.recipient.textilePubkey)
!RegExp(this.$Config.regex.uuidv4).test((this.recipient as Group)?.id)
) {
this.$store.dispatch('textile/sendReplyMessage', {
to: this.recipient.textilePubkey,
to: (this.recipient as Friend).textilePubkey,
text: value,
replyTo: this.ui.replyChatbarContent.messageID,
replyType: MessagingTypesEnum.TEXT,
})
return
}
// Check if it's a group
if (
RegExp(this.$Config.regex.uuidv4).test(
this.recipient.textilePubkey.split('|')[1],
(this.recipient as Group)?.id?.split('|')[1],
)
) {
if (this.ui.replyChatbarContent.from) {
this.$store.dispatch('textile/sendGroupReplyMessage', {
to: this.recipient.textilePubkey,
to: (this.recipient as Group).id,
text: value,
replyTo: this.ui.replyChatbarContent.messageID,
replyType: MessagingTypesEnum.TEXT,
Expand All @@ -326,12 +306,12 @@ export default Vue.extend({
return
}
this.$store.dispatch('textile/sendGroupMessage', {
groupId: this.recipient.textilePubkey,
groupId: (this.recipient as Group).id,
message: value,
})
} else {
this.$store.dispatch('textile/sendTextMessage', {
to: this.recipient.textilePubkey,
to: (this.recipient as Friend).textilePubkey,
text: value,
})
}
Expand Down
15 changes: 4 additions & 11 deletions components/views/chat/chatbar/footer/is-connected/Connected.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
<div
v-if="!typing && $Hounddog.getActiveFriend(friends) && !this.$store.state.textile.conversationLoading"
class="is-connected"
>
<div v-if="!typing && onlineParticipants.length > 0" class="is-connected">
<circle-icon
:class="`status is-${ friendConnected($Hounddog.getActiveFriend(friends).address) ? $t('ui.online') : $t('ui.offline') }`"
:class="`status is-${ onlineParticipants.length > 0 ? $t('ui.online') : $t('ui.offline') }`"
size="1x"
/>
<TypographyText
v-if="$Hounddog.getActiveFriend(friends)"
:text="`${$Hounddog.getActiveFriend(friends).name}`"
v-if="onlineParticipants.length > 0"
:text="onlineParticipantsText"
data-cy="user-connected"
:size="6"
/>
<TypographyText
:text="`is ${ friendConnected($Hounddog.getActiveFriend(friends).address) ? $t('ui.connected') : $t('ui.not_connected') }`"
:size="6"
/>
</div>
Loading

0 comments on commit 505234e

Please sign in to comment.