Skip to content

Commit

Permalink
feat(iridium): group chat (#4376)
Browse files Browse the repository at this point in the history
* feat(profile): set user on profile fetch

* feat(chat): update reactions for user manager

* fix(iridium): replace profile.get() with profile.state

* fix(components): use iridium state

* feat(iridium): create group conversations

* feat(quick): use iridium chat manager

* fix(profile): set account user on load account
  • Loading branch information
jasonwoodland committed Aug 23, 2022
1 parent 03abc13 commit fab8c9d
Show file tree
Hide file tree
Showing 15 changed files with 190 additions and 114 deletions.
2 changes: 1 addition & 1 deletion components/ui/GroupIcon/GroupIcon.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
:type="getSource(member) ? 'image' : 'random'"
:source="getSource(member)"
:size="groupClass == 'multi' ? (i === 2 ? 10 : i == 1 ? 20 : 30) : groupIconSize"
:seed="member.id"
:seed="member.did"
/>
</div>
</div>
Expand Down
22 changes: 7 additions & 15 deletions components/ui/GroupIcon/GroupIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@

<script lang="ts">
import Vue, { PropType } from 'vue'
import {
GroupConfig,
GroupMemberDetails,
} from '~/libraries/Iridium/groups/types'
import { User } from '~/libraries/Iridium/users/types'
export default Vue.extend({
props: {
group: {
type: Object as PropType<GroupConfig>,
members: {
type: Array as PropType<User[]>,
required: true,
},
size: {
Expand All @@ -19,9 +16,6 @@ export default Vue.extend({
},
},
computed: {
members(): GroupMemberDetails[] {
return Object.values(this.group.members)
},
/**
* @method groupClass
* @description Returns classname as string based on group members
Expand All @@ -46,13 +40,11 @@ export default Vue.extend({
/**
* @method getSource
* @description Returns user profile image source hash, stored in IPFS, if they have one
* @param member <GroupMember> the User object/info for a member
* @example :source="getSource(member)"
* @param did
* @example :source="getSource(did)"
*/
getSource(member: GroupMemberDetails) {
return member.photoHash
? this.$Config.ipfs.gateway + member.photoHash
: ''
getSource(user: User) {
return user?.photoHash && this.$Config.ipfs.gateway + user.photoHash
},
},
})
Expand Down
6 changes: 3 additions & 3 deletions components/views/chat/message/Message.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<template v-if="showHeader">
<div class="avatar">
<UiCircle
:type="author.src ? 'image' :'random'"
:seed="author.id"
:source="author.src"
:type="avatarSrc ? 'image' : 'random'"
:seed="author.did"
:source="avatarSrc"
/>
</div>
<div class="header">
Expand Down
22 changes: 8 additions & 14 deletions components/views/chat/message/Message.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
Conversation,
ConversationMessage,
} from '~/libraries/Iridium/chat/types'
import { User } from '~/libraries/Iridium/types'
import { User } from '~/libraries/Iridium/users/types'
import iridium from '~/libraries/Iridium/IridiumManager'
export default Vue.extend({
Expand Down Expand Up @@ -60,19 +60,13 @@ export default Vue.extend({
return this.$route.params.id
},
author(): User {
// TODO: access User from iridium via did
return {
id: this.message.from,
name: 'test',
} as User
// if (this.message.did === iridium.profile.state.
// if (this.conversation.type === 'direct') {
// const friendDid = this.conversation.participants.find(
// (f) => f !== iridium.connector?.id,
// )
// return this.friends.find((f) => f.did === friendDid)
// }
// return this.groups[this.conversation.id]
return iridium.users.getUser(this.message.from)
},
avatarSrc(): string | undefined {
return (
this.author.photoHash &&
this.$Config.ipfs.gateway + this.author.photoHash
)
},
isReplyingTo(): boolean {
return (
Expand Down
4 changes: 2 additions & 2 deletions components/views/chat/message/reactions/Reactions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ export default Vue.extend({
didsForEmoji[emoji].push(did)
})
})
const reactions = Object.entries(didsForEmoji).map(([emoji, names]) => ({
const reactions = Object.entries(didsForEmoji).map(([emoji, dids]) => ({
emoji,
names,
names: dids.map((did) => iridium.users.getUser(did)?.name),
}))
return reactions
},
Expand Down
2 changes: 1 addition & 1 deletion components/views/navigation/sidebar/list/item/Item.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
>
<template>
<UiUserState v-if="conversation.type === 'direct'" :user="user" />
<UiGroupIcon v-else :participants="participants" />
<UiGroupIcon v-else :members="participants" />
</template>
<div class="user-info">
<TypographyText
Expand Down
2 changes: 1 addition & 1 deletion components/views/navigation/sidebar/list/item/Item.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default Vue.extend({
user(): User | null {
return iridium.users.getUser(this.conversation.participants[0])
},
participants(): (User | null)[] {
participants(): User[] {
return this.conversation.participants.map((did) => {
return iridium.users.getUser(did)
})
Expand Down
26 changes: 9 additions & 17 deletions components/views/navigation/sidebar/quick/Quick.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { TranslateResult } from 'vue-i18n'
import iridium from '~/libraries/Iridium/IridiumManager'
import { Friend } from '~/libraries/Iridium/friends/types'
import { RootState } from '~/types/store/store'
import { Conversation } from '~/libraries/Iridium/chat/types'
export default Vue.extend({
data() {
Expand Down Expand Up @@ -53,25 +54,16 @@ export default Vue.extend({
}
this.isLoading = true
try {
if (!this.accounts.details) {
throw new Error('no account')
if (!iridium.connector) {
return
}
const id = await iridium.groups.createGroup({
const participants = [
iridium.connector.id,
...this.friends.map((friend) => friend.did),
]
const id = await iridium.chat.createGroupConversation({
name: this.name,
members: {
[this.accounts.active]: {
id: this.accounts.active,
name: this.accounts.details.name,
photoHash: this.accounts.details.profilePicture,
},
...this.friends.reduce(
(prev, f) => ({
...prev,
[f.did]: { id: f.did, name: f.name, photoHash: f.photoHash },
}),
{},
),
},
participants,
})
this.$emit('toggle')
this.$router.push(`/chat/${id}`)
Expand Down
2 changes: 1 addition & 1 deletion components/views/navigation/toolbar/Toolbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div class="circle-container">
<template v-if="details">
<UiUserState v-if="!isGroup" class="circle" :user="details" />
<UiGroupIcon v-else :group="details" />
<UiGroupIcon v-else :members="members" />
</template>
</div>
<div class="user-info">
Expand Down
43 changes: 17 additions & 26 deletions components/views/navigation/toolbar/Toolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ export default Vue.extend({
default: false,
},
},
setup() {
const { isActiveCall } = useWebRTC()
return { isActiveCall }
},
data() {
return {
searchRecommend,
Expand All @@ -53,6 +48,7 @@ export default Vue.extend({
groups: iridium.groups.state,
isGroupInviteVisible: false,
webrtc: iridium.webRTC.state,
isActiveCall: undefined as any,
}
},
computed: {
Expand All @@ -64,50 +60,42 @@ export default Vue.extend({
modals: (state) => (state as RootState).ui.modals,
}),
ModalWindows: () => ModalWindows,
conversationId(): Conversation['id'] | undefined {
conversationId(): string {
return this.$route.params.id
},
conversation(): Conversation | undefined {
if (!this.conversationId) {
return undefined
}
conversation(): Conversation {
return iridium.chat.state.conversations[this.conversationId]
},
isGroup(): boolean {
return this.conversation?.type === 'group'
return this.conversation.participants.length > 2
},
details(): User | Group | undefined {
if (!this.conversation) {
return undefined
}
details(): User | Conversation {
if (this.isGroup) {
return this.groups[this.conversation.id]
return iridium.chat.state.conversations[this.conversationId]
}
const friendDid = this.conversation.participants.find(
(f) => f !== iridium.connector?.id,
)
if (!friendDid) {
return
}
) as string
return this.users[friendDid]
},
groupMembers(): GroupMemberDetails[] {
const members = (this.details as Group).members ?? []
return Object.values(members)
members(): User[] {
return this.conversation.participants.map((did) => {
return iridium.users.getUser(did)
})
},
subtitleText(): string {
if (!this.details) {
return ''
}
if (this.isGroup) {
return this.groupMembers.map((m) => m.name).join(', ')
return this.members.map((m) => m.name).join(', ')
}
return (this.details as User).status || 'offline'
},
enableRTC(): boolean {
// todo- hook up to usermanager
if (this.isGroup) {
const memberIds = this.groupMembers.map((m) => m.id)
const memberIds = this.members.map((m) => m.did)
return Object.values(this.users).some(
(friend: Friend) =>
memberIds.includes(friend.did) && friend.status === 'online',
Expand All @@ -128,11 +116,14 @@ export default Vue.extend({
: (this.$t('controls.not_connected') as string)
},
},
mounted() {
this.isActiveCall = useWebRTC()
},
methods: {
groupInvite() {
this.$store.commit('ui/toggleModal', {
name: 'groupInvite',
state: { isOpen: true, group: this.details as Group },
state: { isOpen: true, group: this.details as Conversation },
})
},
toggleAlerts() {
Expand Down
Loading

0 comments on commit fab8c9d

Please sign in to comment.