From 121e370be3c6057bc3b62f26453c0db451c96f0f Mon Sep 17 00:00:00 2001 From: Drew Ewing Date: Mon, 29 Aug 2022 14:56:28 -0700 Subject: [PATCH 1/3] feat(refactor): pre-launch cleanup (wip, will be broken up) --- .../interactables/UserPicker/UserPicker.vue | 4 +- .../ui/BackgroundCall/BackgroundCall.vue | 34 +- .../Chat/TypingIndicator/TypingIndicator.vue | 13 +- components/ui/Global/Global.html | 2 +- components/ui/Global/Global.vue | 16 +- components/ui/User/State/State.vue | 31 +- components/views/chat/chatbar/Chatbar.vue | 2 +- .../views/chat/chatbar/footer/Footer.vue | 15 +- .../views/chat/conversation/Conversation.vue | 28 +- components/views/chat/message/Message.vue | 8 +- .../views/chat/message/actions/Actions.vue | 3 +- components/views/friends/friend/Friend.html | 1 + components/views/friends/friend/Friend.vue | 5 +- .../views/friends/requests/Requests.vue | 3 +- components/views/friends/search/Search.vue | 54 +- components/views/group/invite/Invite.vue | 3 +- components/views/media/Media.vue | 16 +- components/views/media/actions/Actions.vue | 2 +- components/views/media/heading/Heading.html | 4 +- components/views/media/heading/Heading.vue | 17 +- .../views/media/incomingCall/IncomingCall.vue | 3 +- .../views/media/previewCall/PreviewCall.vue | 19 +- components/views/media/user/User.vue | 49 +- .../navigation/mobile/toolbar/Toolbar.vue | 48 +- .../views/navigation/sidebar/Sidebar.vue | 4 +- .../views/navigation/sidebar/list/List.html | 2 +- .../views/navigation/sidebar/list/List.vue | 13 +- .../navigation/sidebar/list/item/Item.html | 10 +- .../navigation/sidebar/list/item/Item.vue | 37 +- .../views/navigation/sidebar/live/Live.vue | 5 +- .../views/navigation/sidebar/quick/Quick.vue | 1 - .../navigation/sidebar/status/Status.vue | 12 +- .../views/navigation/toolbar/Toolbar.html | 8 +- .../views/navigation/toolbar/Toolbar.vue | 30 +- .../navigation/toolbar/alerts/Alerts.html | 33 +- .../navigation/toolbar/alerts/Alerts.less | 5 +- .../navigation/toolbar/alerts/Alerts.vue | 18 +- .../toolbar/alerts/alert/Alert.html | 14 +- .../navigation/toolbar/alerts/alert/Alert.vue | 8 +- .../views/settings/pages/accounts/index.vue | 9 +- libraries/Iridium/IridiumManager.ts | 39 +- libraries/Iridium/NotificationManager.ts | 92 +-- libraries/Iridium/chat/ChatManager.ts | 282 ++++---- libraries/Iridium/chat/types.ts | 5 +- libraries/Iridium/friends/FriendsManager.ts | 168 +++-- libraries/Iridium/groups/GroupManager.ts | 51 +- libraries/Iridium/profile/ProfileManager.ts | 20 +- libraries/Iridium/users/UsersManager.ts | 132 ++-- libraries/Iridium/webrtc/WebRTCManager.ts | 610 ++++++------------ libraries/Iridium/webrtc/hooks.ts | 129 ---- libraries/Iridium/webrtc/types.ts | 2 +- libraries/WebRTC/Call.ts | 2 +- pages/chat/_id.vue | 15 +- pages/friends/index.vue | 8 +- pages/index.vue | 4 + store/accounts/actions.ts | 19 +- store/audio/actions.ts | 7 + 57 files changed, 991 insertions(+), 1183 deletions(-) delete mode 100644 libraries/Iridium/webrtc/hooks.ts diff --git a/components/interactables/UserPicker/UserPicker.vue b/components/interactables/UserPicker/UserPicker.vue index 0abf21d16e..046055d5c0 100644 --- a/components/interactables/UserPicker/UserPicker.vue +++ b/components/interactables/UserPicker/UserPicker.vue @@ -20,11 +20,11 @@ export default Vue.extend({ data: () => ({ selected: [] as Friend[], filter: '', - friendDids: iridium.friends.state.friends, + fm: iridium.friends.state, }), computed: { friends() { - return Object.values(this.friendDids) + return Object.values(this.fm.friends) .filter((did) => !this.exclude.includes(did)) .map((did) => { return iridium.users.getUser(did) diff --git a/components/ui/BackgroundCall/BackgroundCall.vue b/components/ui/BackgroundCall/BackgroundCall.vue index 739a31b8d9..c35d31c731 100644 --- a/components/ui/BackgroundCall/BackgroundCall.vue +++ b/components/ui/BackgroundCall/BackgroundCall.vue @@ -3,45 +3,17 @@ diff --git a/components/views/media/incomingCall/IncomingCall.vue b/components/views/media/incomingCall/IncomingCall.vue index 00b0c9f3f8..6cdbf404d0 100644 --- a/components/views/media/incomingCall/IncomingCall.vue +++ b/components/views/media/incomingCall/IncomingCall.vue @@ -37,6 +37,7 @@ export default Vue.extend({ data() { return { webrtc: iridium.webRTC.state, + chat: iridium.chat.state, } }, computed: { @@ -47,7 +48,7 @@ export default Vue.extend({ if (!this.conversationId) { return undefined } - return iridium.chat.state.conversations[this.conversationId] + return this.chat.conversations[this.conversationId] }, isGroup(): boolean { return this.conversation?.type === 'group' diff --git a/components/views/media/previewCall/PreviewCall.vue b/components/views/media/previewCall/PreviewCall.vue index ec195bf93c..f667b1a79c 100644 --- a/components/views/media/previewCall/PreviewCall.vue +++ b/components/views/media/previewCall/PreviewCall.vue @@ -4,7 +4,6 @@ import Vue from 'vue' import { CornerUpLeftIcon } from 'satellite-lucide-icons' import iridium from '~/libraries/Iridium/IridiumManager' -import { useWebRTC } from '~/libraries/Iridium/webrtc/hooks' export default Vue.extend({ components: { @@ -16,20 +15,14 @@ export default Vue.extend({ default: false, }, }, - setup() { - const { remoteParticipants } = useWebRTC() - - const remoteParticipant = computed(() => { - return remoteParticipants.value.length > 0 - ? remoteParticipants.value[0] - : null - }) - - return { remoteParticipant } + data() { + return { + webrtc: iridium.webRTC.state, + } }, methods: { navigateToActiveConversation() { - if (!iridium.webRTC.state.activeCall?.callId) { + if (!this.webrtc.activeCall) { return } if (this.$device.isMobile) { @@ -37,7 +30,7 @@ export default Vue.extend({ this.$store.commit('ui/setSwiperSlideIndex', 1) this.$store.commit('ui/showSidebar', false) } - this.$router.push(`/chat/${iridium.webRTC.state.activeCall.callId}`) + this.$router.push(`/chat/${this.webrtc.activeCall.callId}`) }, }, }) diff --git a/components/views/media/user/User.vue b/components/views/media/user/User.vue index 61b3acccef..3bed982916 100644 --- a/components/views/media/user/User.vue +++ b/components/views/media/user/User.vue @@ -13,7 +13,8 @@ import { AudioStreamUtils } from '~/utilities/AudioStreamUtils' import { User } from '~/libraries/Iridium/friends/types' import { RootState } from '~/types/store/store' import iridium from '~/libraries/Iridium/IridiumManager' -import { useUserStreams, useWebRTC } from '~/libraries/Iridium/webrtc/hooks' +import { $WebRTC } from '~/libraries/WebRTC/WebRTC' +import { WebRTCEnum } from '~/libraries/Enums/enums' export default Vue.extend({ components: { @@ -36,22 +37,10 @@ export default Vue.extend({ default: false, }, }, - setup(props) { - const { call } = useWebRTC() - const { streams, getStream } = useUserStreams(props.user.did) - - return { - call, - streams, - audioStream: getStream('audio'), - videoStream: getStream('video'), - screenStream: getStream('screen'), - } - }, data() { return { - videoSettings: iridium.settings.state.video, webrtc: iridium.webRTC.state, + videoSettings: iridium.settings.state.video, isTalking: false, audioStreamUtils: null as AudioStreamUtils | null, } @@ -61,6 +50,14 @@ export default Vue.extend({ audio: (state) => (state as RootState).audio, video: (state) => (state as RootState).video, }), + call() { + if (!this.webrtc.activeCall?.callId) return + return $WebRTC.getCall(this.webrtc.activeCall.callId) + }, + streams() { + if (!this.user.did || !this.call) return + return this.call.streams[this.user.did] + }, src(): string { const hash = this.user.photoHash return hash ? `${this.$Config.ipfs.gateway}${hash}` : '' @@ -68,10 +65,22 @@ export default Vue.extend({ isPending(): boolean { return Boolean( this.user.did !== iridium.connector?.id && - this.call && - !this.webrtc.createdAt, + this.webrtc.activeCall && + !this.webrtc.callStartedAt, ) }, + audioStream() { + if (this.isMuted('audio') || !this.call) return + return this.streams?.audio + }, + videoStream() { + if (this.isMuted('video') || !this.call) return + return this.streams?.video + }, + screenStream() { + if (this.isMuted('screen') || !this.call) return + return this.streams?.screen + }, }, watch: { audioStream(stream) { @@ -104,6 +113,14 @@ export default Vue.extend({ beforeDestroy() { this.audioStreamUtils?.destroy() }, + methods: { + isMuted(kind: WebRTCEnum) { + return ( + !this.user.did || + Boolean(this.webrtc.streamMuted[this.user.did]?.[kind] ?? true) + ) + }, + }, }) diff --git a/components/views/navigation/mobile/toolbar/Toolbar.vue b/components/views/navigation/mobile/toolbar/Toolbar.vue index fffc4ff7bd..f7df8d06c5 100644 --- a/components/views/navigation/mobile/toolbar/Toolbar.vue +++ b/components/views/navigation/mobile/toolbar/Toolbar.vue @@ -13,10 +13,10 @@ import { mapGetters } from 'vuex' import iridium from '~/libraries/Iridium/IridiumManager' import Group from '~/libraries/Iridium/groups/Group' import { TrackKind } from '~/libraries/WebRTC/types' -import type { User } from '~/libraries/Iridium/friends/types' +import type { Friend, User } from '~/libraries/Iridium/friends/types' import { Conversation } from '~/libraries/Iridium/chat/types' import { GroupMemberDetails } from '~/libraries/Iridium/groups/types' -import { useWebRTC } from '~/libraries/Iridium/webrtc/hooks' +import { GroupState } from '~/libraries/Iridium/groups/GroupManager' export default Vue.extend({ components: { @@ -25,21 +25,20 @@ export default Vue.extend({ MenuIcon, VideoIcon, }, - setup() { - const { isActiveCall } = useWebRTC() - - return { isActiveCall } - }, data() { return { users: iridium.users.state, groups: iridium.groups.state, isGroupInviteVisible: false, webrtc: iridium.webRTC.state, + chat: iridium.chat.state, } }, computed: { ...mapGetters('ui', ['allUnseenNotifications']), + isActiveCall() { + return iridium.webRTC.isActiveCall(this.$route.params.id) + }, conversationId(): Conversation['id'] | undefined { return this.$route.params.id }, @@ -47,20 +46,20 @@ export default Vue.extend({ if (!this.conversationId) { return undefined } - return iridium.chat.state.conversations[this.conversationId] + return this.chat.conversations[this.conversationId] }, isGroup(): boolean { return this.conversation?.type === 'group' }, - details(): User | Group | undefined { + details(): User | GroupState | undefined { if (!this.conversation) { return undefined } if (this.isGroup) { return this.groups[this.conversation.id] } - const friendDid = this.conversation.participants.find( - (f) => f !== iridium.connector?.id, + const friendDid = this.conversation?.participants.find( + (f: string) => f !== iridium.connector?.id, ) if (!friendDid) { return @@ -68,24 +67,21 @@ export default Vue.extend({ return this.users[friendDid] }, groupMembers(): GroupMemberDetails[] { - const members = (this.details as Group).members ?? [] + const members = (this.details as GroupState).members ?? [] return Object.values(members) }, enableRTC(): boolean { + console.info('enableRTC', this.details, this.isGroup) // todo- hook up to usermanager - return false - // if (this.isGroup) { - // const memberIds = this.groupMembers.map((m) => m.id) - // return this.friends.some( - // (friend: Friend) => - // memberIds.includes(friend.did) && friend.status === 'online', - // ) - // } - // // Check current recipient is on the user's friends list - // const friend = this.friends.find( - // (f) => f.did === (this.details as User)?.did, - // ) - // return friend?.status === 'online' + if (this.isGroup) { + const memberIds = this.groupMembers.map((m) => m.id) + return this.friends.some( + (friend: Friend) => + memberIds.includes(friend.did) && friend.status === 'online', + ) + } + // Check current recipient is on the user's friends list + return this.details?.status === 'online' }, }, methods: { @@ -94,7 +90,7 @@ export default Vue.extend({ return } try { - await iridium.webRTC.call(this.details, kinds) + await iridium.webRTC.call(this.details as Friend, kinds) } catch (e: any) { this.$toast.error(this.$t(e.message) as string) } diff --git a/components/views/navigation/sidebar/Sidebar.vue b/components/views/navigation/sidebar/Sidebar.vue index 6c660d65a4..3a6e00a7ff 100644 --- a/components/views/navigation/sidebar/Sidebar.vue +++ b/components/views/navigation/sidebar/Sidebar.vue @@ -17,12 +17,12 @@ export default Vue.extend({ data() { return { isQuickchatVisible: false, - requests: iridium.friends.state.requests, + friends: iridium.friends.state, } }, computed: { incomingRequestsLength(): number { - return Object.values(this.requests).filter( + return Object.values(this.friends.requests).filter( (r: FriendRequest) => r.status === 'pending' && r.incoming, ).length }, diff --git a/components/views/navigation/sidebar/list/List.html b/components/views/navigation/sidebar/list/List.html index 0acc25f806..6ced8198f9 100644 --- a/components/views/navigation/sidebar/list/List.html +++ b/components/views/navigation/sidebar/list/List.html @@ -2,7 +2,7 @@ diff --git a/components/views/navigation/sidebar/list/List.vue b/components/views/navigation/sidebar/list/List.vue index d0f5827a4e..5ef5aef901 100644 --- a/components/views/navigation/sidebar/list/List.vue +++ b/components/views/navigation/sidebar/list/List.vue @@ -10,12 +10,15 @@ export default Vue.extend({ components: { UserPlusIcon, }, - data: () => ({ - conversations: iridium.chat.state.conversations, - }), + data() { + return { + chat: iridium.chat.state, + users: iridium.users.state, + } + }, computed: { sortedConversations(): Conversation[] { - return Object.values(this.conversations).sort( + return Object.values(this.chat.conversations).sort( (a, b) => this.lastMessageTimestamp(b) - this.lastMessageTimestamp(a), ) }, @@ -23,7 +26,7 @@ export default Vue.extend({ methods: { lastMessageTimestamp(conversation: Conversation): number { const messages = Object.values( - this.conversations[conversation.id].message, + this.chat.conversations[conversation.id].message, ).sort((a, b) => a.at - b.at) return messages.at(-1)?.at ?? (conversation.updatedAt || 0) }, diff --git a/components/views/navigation/sidebar/list/item/Item.html b/components/views/navigation/sidebar/list/item/Item.html index 521fdc708b..dd733d7de3 100644 --- a/components/views/navigation/sidebar/list/item/Item.html +++ b/components/views/navigation/sidebar/list/item/Item.html @@ -6,8 +6,14 @@ data-cy="sidebar-user" >