Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into sebin/task/#2341-an…
Browse files Browse the repository at this point in the history
…yone-can-join-invite-issue
  • Loading branch information
SebinSong committed Sep 13, 2024
2 parents c1f86a4 + ca27856 commit 4c72344
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 51 deletions.
4 changes: 3 additions & 1 deletion frontend/controller/actions/identity.js
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,9 @@ export default (sbp('sbp/selectors/register', {
const rootState = sbp('state/vuex/state')
// TODO: Can't use rootGetters
const rootGetters = sbp('state/vuex/getters')
const partnerIDs = params.data.memberIDs.map(memberID => rootGetters.ourContactProfilesById[memberID].contractID)
const partnerIDs = params.data.memberIDs
.filter(memberID => memberID !== rootGetters.ourIdentityContractId)
.map(memberID => rootGetters.ourContactProfilesById[memberID].contractID)
// NOTE: 'rootState.currentGroupId' could be changed while waiting for the sbp functions to be proceeded
// So should save it as a constant variable 'currentGroupId', and use it which can't be changed
const currentGroupId = rootState.currentGroupId
Expand Down
36 changes: 27 additions & 9 deletions frontend/model/chatroom/vuexModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,28 @@ const getters = {
for (const chatRoomID of Object.keys(getters.ourDirectMessages)) {
const chatRoomState = rootState[chatRoomID]
const directMessageSettings = getters.ourDirectMessages[chatRoomID]
const myIdendityId = getters.ourIdentityContractId

// NOTE: skip DMs whose chatroom contracts are not synced yet
if (!chatRoomState || !chatRoomState.members?.[getters.ourIdentityContractId]) {
if (!chatRoomState || !chatRoomState.members?.[myIdendityId]) {
continue
}
// NOTE: direct messages should be filtered to the ones which are visible and of active group members
const members = Object.keys(chatRoomState.members)
const isDMToMyself = members.length === 1 && members[0] === myIdendityId
const partners = members
.filter(memberID => memberID !== getters.ourIdentityContractId)
.filter(memberID => memberID !== myIdendityId)
.sort((p1, p2) => {
const p1JoinedDate = new Date(chatRoomState.members[p1].joinedDate).getTime()
const p2JoinedDate = new Date(chatRoomState.members[p2].joinedDate).getTime()
return p1JoinedDate - p2JoinedDate
})
const hasActiveMember = partners.some(memberID => Object.keys(getters.profilesByGroup(groupID)).includes(memberID))
if (directMessageSettings.visible && hasActiveMember) {
if (directMessageSettings.visible && (isDMToMyself || hasActiveMember)) {
// NOTE: lastJoinedParter is chatroom member who has joined the chatroom for the last time.
// His profile picture can be used as the picture of the direct message
// possibly with the badge of the number of partners.
const lastJoinedPartner = partners[partners.length - 1]
const lastJoinedPartner = isDMToMyself ? myIdendityId : partners[partners.length - 1]
const lastMsgTimeStamp = chatRoomState.messages?.length > 0
? new Date(chatRoomState.messages[chatRoomState.messages.length - 1].datetime).getTime()
: 0
Expand All @@ -80,9 +82,12 @@ const getters = {
// identity contract IDs differently in some way (e.g., font, font size,
// prefix (@), etc.) to make it impossible (or at least obvious) to impersonate
// users (e.g., 'user1' changing their display name to 'user2')
title: partners.map(cID => getters.userDisplayNameFromID(cID)).join(', '),
title: isDMToMyself
? getters.userDisplayNameFromID(myIdendityId)
: partners.map(cID => getters.userDisplayNameFromID(cID)).join(', '),
lastMsgTimeStamp,
picture: getters.ourContactProfilesById[lastJoinedPartner]?.picture
picture: getters.ourContactProfilesById[lastJoinedPartner]?.picture,
isDMToMyself // Can be useful when certain things in UI are meant only for 'DM to myself'
}
}
}
Expand All @@ -95,15 +100,22 @@ const getters = {
// NOTE: this getter is used to find the ID of the direct message in the current group
// with the name[s] of partner[s]. Normally it's more useful to find direct message
// by the partners instead of contractID
ourGroupDirectMessageFromUserIds (state, getters) {
ourGroupDirectMessageFromUserIds (state, getters, rootState) {
return (partners) => { // NOTE: string | string[]
if (typeof partners === 'string') {
partners = [partners]
}

const shouldFindDMToMyself = partners.length === 1 && partners[0] === rootState.loggedIn.identityContractID
const currentGroupDirectMessages = getters.ourGroupDirectMessages
return Object.keys(currentGroupDirectMessages).find(chatRoomID => {
const cPartners = currentGroupDirectMessages[chatRoomID].partners.map(partner => partner.contractID)
return cPartners.length === partners.length && union(cPartners, partners).length === partners.length
const chatRoomSettings = currentGroupDirectMessages[chatRoomID]

if (shouldFindDMToMyself) return chatRoomSettings.isDMToMyself
else {
const cPartners = chatRoomSettings.partners.map(partner => partner.contractID)
return cPartners.length === partners.length && union(cPartners, partners).length === partners.length
}
})
}
},
Expand All @@ -115,6 +127,12 @@ const getters = {
// NOTE: identity contract could not be synced at the time of calling this getter
return chatRoomID => !!getters.ourDirectMessages[chatRoomID || getters.currentChatRoomId]
},
isGroupDirectMessageToMyself (state, getters) {
return chatRoomID => {
const chatRoomSettings = getters.ourGroupDirectMessages[chatRoomID || getters.currentChatRoomId]
return !!chatRoomSettings && chatRoomSettings?.isDMToMyself
}
},
isJoinedChatRoom (state, getters, rootState) {
return (chatRoomID: string, memberID?: string) => !!rootState[chatRoomID]?.members?.[memberID || getters.ourIdentityContractId]
},
Expand Down
5 changes: 0 additions & 5 deletions frontend/views/components/UsersSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ export default ({
if (keyCode === 13 || keyCode === 39) { // Enter
this.$emit('submit')
return
} else if (keyCode === 8 && !this.value && this.usernames.length) { // Backspace
this.remove(this.usernames[this.usernames.length - 1])
}
this.value = this.$refs.input.textContent
Expand All @@ -117,9 +115,6 @@ export default ({
watch: {
value () {
this.$emit('change', this.value)
},
usernames () {
this.clear()
}
}
}: Object)
Expand Down
2 changes: 2 additions & 0 deletions frontend/views/containers/chatroom/ChatMain.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
:creatorID='summary.attributes.creatorID'
:type='summary.attributes.type'
:joined='summary.isJoined'
:dm-to-myself='summary.isDMToMySelf'
:name='summary.title'
:description='summary.attributes.description'
)
Expand All @@ -43,6 +44,7 @@
:creatorID='summary.attributes.creatorID'
:type='summary.attributes.type'
:joined='summary.isJoined'
:dm-to-myself='summary.isDMToMySelf'
:name='summary.title'
:description='summary.attributes.description'
)
Expand Down
38 changes: 27 additions & 11 deletions frontend/views/containers/chatroom/ChatMembers.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,31 @@

ul.c-group-list
list-item(
v-for='({ partners, title, picture }, chatRoomID) in ourGroupDirectMessages'
v-for='({ partners, title, picture, isDMToMyself }, chatRoomID) in ourGroupDirectMessages'
tag='router-link'
:to='buildUrl(chatRoomID)'
:data-test='chatRoomID'
:key='chatRoomID'
@click='$emit("redirect")'
)
.profile-wrapper(v-if='partners.length === 1')
profile-card(:contractID='partners[0].contractID' deactivated)
avatar-user(:contractID='partners[0].contractID' :picture='picture' size='sm' data-test='openMemberProfileCard')
span.is-unstyled.c-name.has-ellipsis(:data-test='partners[0].username') {{ title }}

.group-wrapper(v-else)
.picture-wrapper
avatar(:src='picture' :alt='title' size='xs')
.c-badge {{ partners.length }}
span.is-unstyled.c-name.has-ellipsis(:data-test='title') {{ title }}
.profile-wrapper(v-if='isDMToMyself')
profile-card(:contractID='ourIdentityContractId' deactivated)
avatar-user(:contractID='ourIdentityContractId' :picture='picture' size='sm' data-test='openMemberProfileCard')
span.is-unstyled.c-name.has-ellipsis(:data-test='title')
span {{ title }}
i18n.c-you (you)

template(v-else)
.profile-wrapper(v-if='partners.length === 1')
profile-card(:contractID='partners[0].contractID' deactivated)
avatar-user(:contractID='partners[0].contractID' :picture='picture' size='sm' data-test='openMemberProfileCard')
span.is-unstyled.c-name.has-ellipsis(:data-test='partners[0].username') {{ title }}

.group-wrapper(v-else)
.picture-wrapper
avatar(:src='picture' :alt='title' size='xs')
.c-badge {{ partners.length }}
span.is-unstyled.c-name.has-ellipsis(:data-test='title') {{ title }}

.c-unreadcount-wrapper
.pill.is-danger(
Expand Down Expand Up @@ -71,6 +79,7 @@ export default ({
...mapGetters([
'groupShouldPropose',
'ourGroupDirectMessages',
'ourIdentityContractId',
'chatRoomUnreadMessages'
])
},
Expand Down Expand Up @@ -143,6 +152,13 @@ export default ({
border-bottom: 1px solid transparent;
}
.c-you {
display: inline-block;
margin-left: 0.25rem;
font-size: 0.875em;
font-weight: normal;
}
.c-menu {
margin-left: 0.5rem;
}
Expand Down
21 changes: 15 additions & 6 deletions frontend/views/containers/chatroom/ChatMixin.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import sbp from '@sbp/sbp'
import { mapGetters, mapState } from 'vuex'
import { CHATROOM_PRIVACY_LEVEL, PROFILE_STATUS } from '@model/contracts/shared/constants.js'
import { CHATROOM_PRIVACY_LEVEL, CHATROOM_TYPES, PROFILE_STATUS } from '@model/contracts/shared/constants.js'
import { logExceptNavigationDuplicated } from '@view-utils/misc.js'

const initSummary = {
Expand All @@ -9,6 +9,7 @@ const initSummary = {
picture: undefined,
attributes: {},
isPrivate: false,
isDMToMySelf: false,
isGeneral: false,
isJoined: false,
members: {},
Expand Down Expand Up @@ -45,8 +46,10 @@ const ChatMixin: Object = {
'globalProfile',
'isJoinedChatRoom',
'ourContactProfilesById',
'ourIdentityContractId',
'isDirectMessage',
'isGroupDirectMessage'
'isGroupDirectMessage',
'isGroupDirectMessageToMyself'
]),
...mapState(['currentGroupId']),
summary (): Object {
Expand All @@ -60,16 +63,23 @@ const ChatMixin: Object = {
title = this.ourGroupDirectMessages[this.currentChatRoomId].title
picture = this.ourGroupDirectMessages[this.currentChatRoomId].picture
}
const chatroomMemberKeys = Object.keys(this.currentChatRoomState.members)
const isPrivate = this.currentChatRoomState.attributes.privacyLevel === CHATROOM_PRIVACY_LEVEL.PRIVATE
const isDMToMySelf = isPrivate &&
this.currentChatRoomState.attributes.type === CHATROOM_TYPES.DIRECT_MESSAGE &&
chatroomMemberKeys.length === 1 &&
chatroomMemberKeys[0] === this.ourIdentityContractId

return {
chatRoomID: this.currentChatRoomId,
title,
picture,
attributes: Object.assign({}, this.currentChatRoomState.attributes),
isPrivate: this.currentChatRoomState.attributes.privacyLevel === CHATROOM_PRIVACY_LEVEL.PRIVATE,
isPrivate,
isDMToMySelf,
isGeneral: this.groupGeneralChatRoomId === this.currentChatRoomId,
isJoined: true,
members: Object.fromEntries(Object.keys(this.currentChatRoomState.members).map(memberID => {
members: Object.fromEntries(chatroomMemberKeys.map(memberID => {
const { displayName, picture, email } = this.globalProfile(memberID) || {}
return [memberID, { ...this.currentChatRoomState.members[memberID], displayName, picture, email }]
})),
Expand Down Expand Up @@ -104,8 +114,7 @@ const ChatMixin: Object = {
const summarizedAttr = this.groupChatRooms[chatRoomID]
if (summarizedAttr) {
const { creator, name, description, type, privacyLevel, members } = summarizedAttr
const activeMembers = Object
.entries(members)
const activeMembers = Object.entries(members)
.filter(([, profile]) => (profile: any)?.status === PROFILE_STATUS.ACTIVE)
.map(([username]) => {
const { displayName, picture, email } = this.globalProfile(username) || {}
Expand Down
7 changes: 7 additions & 0 deletions frontend/views/containers/chatroom/ConversationGreetings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export default ({
creatorID: {
type: String
},
dmToMyself: {
type: Boolean
},
type: {
type: String
},
Expand All @@ -57,6 +60,10 @@ export default ({
computed: {
...mapGetters(['ourIdentityContractId', 'isGroupDirectMessage']),
text () {
if (this.dmToMyself) {
return L('You can post private notes to yourself here.')
}
return {
GIBot: L('I’m here to keep you update while you are away.'),
// TODO: need to change text
Expand Down
Loading

0 comments on commit 4c72344

Please sign in to comment.