Fix circle leave and visible/member checks

Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
This commit is contained in:
John Molakvoæ (skjnldsv) 2021-03-10 09:12:52 +01:00
parent 0538d6a7cf
commit 21c5e699ff
No known key found for this signature in database
GPG Key ID: 60C25B8C072916CF
5 changed files with 89 additions and 45 deletions

View File

@ -76,8 +76,8 @@
</ActionButton>
</template>
<AppNavigationCounter v-if="circle.members.length > 0" slot="counter">
{{ circle.members.length }}
<AppNavigationCounter v-if="memberCount > 0" slot="counter">
{{ memberCount }}
</AppNavigationCounter>
</AppNavigationItem>
</template>
@ -121,7 +121,7 @@ export default {
data() {
return {
loading: false
loading: false,
}
},
@ -145,6 +145,10 @@ export default {
}
return t('contacts', 'Join circle')
},
memberCount() {
return this.circle?.members?.length || 0
},
},
methods: {
@ -162,7 +166,21 @@ export default {
},
leaveCircle() {
async leaveCircle() {
this.loading = true
const member = this.circle.initiator
try {
await this.$store.dispatch('deleteMemberFromCircle', {
member,
leave: true,
})
} catch (error) {
console.error('Could not leave the circle', member, error)
showError(t('contacts', 'Could not leave the circle {displayName}', this.circle))
} finally {
this.loading = false
}
},

View File

@ -61,8 +61,16 @@
:size="16"
decorative />
</ActionButton>
<ActionButton v-if="canDelete" icon="icon-delete" @click="deleteMember">
{{ deleteMemberName }}
<!-- Leave or delete member from circle -->
<ActionButton v-if="isCurrentUser && !circle.isOwner" @click="deleteMember">
{{ t('contacts', 'Leave circle') }}
<ExitToApp slot="icon"
:size="16"
decorative />
</ActionButton>
<ActionButton v-else-if="canDelete" icon="icon-delete" @click="deleteMember">
{{ t('contacts', 'Remove member') }}
</ActionButton>
</template>
</Actions>
@ -77,13 +85,14 @@ import ListItemIcon from '@nextcloud/vue/dist/Components/ListItemIcon'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import ActionText from '@nextcloud/vue/dist/Components/ActionText'
import ShieldCheck from 'vue-material-design-icons/ShieldCheck'
import ArrowLeft from 'vue-material-design-icons/ArrowLeft'
import ExitToApp from 'vue-material-design-icons/ExitToApp'
import ShieldCheck from 'vue-material-design-icons/ShieldCheck'
import RouterMixin from '../../mixins/RouterMixin'
import Member from '../../models/member'
import { showError } from '@nextcloud/dialogs'
import { changeMemberLevel } from '../../services/circles'
import { showError } from '@nextcloud/dialogs'
import Member from '../../models/member'
import RouterMixin from '../../mixins/RouterMixin'
export default {
name: 'MemberListItem',
@ -93,6 +102,7 @@ export default {
ActionButton,
ActionText,
ArrowLeft,
ExitToApp,
ListItemIcon,
ShieldCheck,
},
@ -115,6 +125,10 @@ export default {
},
computed: {
/**
* Return the current circle
* @returns {Circle}
*/
circle() {
return this.$store.getters.getCircle(this.selectedCircle)
},
@ -135,12 +149,6 @@ export default {
|| CIRCLES_MEMBER_LEVELS[MEMBER_LEVEL_MEMBER]
},
deleteMemberName() {
return this.isCurrentUser
? t('contacts', 'Leave this circle')
: t('contacts', 'Remove member')
},
/**
* Current user member level
* @returns {number}
@ -186,7 +194,7 @@ export default {
},
/**
* Can the current user delete members?
* Can the current user delete members or?
* @returns {boolean}
*/
canDelete() {

View File

@ -24,7 +24,7 @@
import {
MEMBER_LEVEL_MODERATOR, MEMBER_LEVEL_NONE, MEMBER_LEVEL_OWNER,
CIRCLE_CONFIG_REQUEST, CIRCLE_CONFIG_INVITE, CIRCLE_CONFIG_OPEN,
CIRCLE_CONFIG_REQUEST, CIRCLE_CONFIG_INVITE, CIRCLE_CONFIG_OPEN, CIRCLE_CONFIG_VISIBLE,
} from './constants'
import Vue from 'vue'
@ -33,15 +33,25 @@ import Member from './member'
export default class Circle {
_data = {}
_members = {}
/**
* Creates an instance of Contact
* Creates an instance of Circle
*
* @param {Object} data the vcard data as string with proper new lines
* @param {object} circle the addressbook which the contat belongs to
* @memberof Circle
*/
constructor(data) {
this.updateData(data)
}
/**
* Update inner circle data, owner and initiator
* @param {Object} data the vcard data as string with proper new lines
* @memberof Circle
*/
updateData(data) {
if (typeof data !== 'object') {
throw new Error('Invalid circle')
}
@ -52,9 +62,8 @@ export default class Circle {
}
this._data = data
this._data.initiator = new Member(data.initiator)
this._data.initiator = new Member(data.initiator, this)
this._data.owner = new Member(data.owner)
this._data.members = {}
}
// METADATA -----------------------------------------
@ -148,7 +157,7 @@ export default class Circle {
* @returns {Member[]}
*/
get members() {
return this._data.members
return this._members
}
/**
@ -157,7 +166,7 @@ export default class Circle {
* @memberof Circle
*/
set members(members) {
this._data.members = members
this._members = members
}
/**
@ -170,10 +179,10 @@ export default class Circle {
}
const uid = member.id
if (this._data.members[uid]) {
console.warn('Duplicate member overrided', this._data.members[uid], member)
if (this._members[uid]) {
console.warn('Duplicate member overrided', this._members[uid], member)
}
Vue.set(this._data.members, uid, member)
Vue.set(this._members, uid, member)
}
/**
@ -186,12 +195,12 @@ export default class Circle {
}
const uid = member.id
if (!this._data.members[uid]) {
if (!this._members[uid]) {
console.warn('The member was not in this circle. Nothing was done.', member)
}
// Delete and clear memory
Vue.delete(this._data.members, uid)
Vue.delete(this._members, uid)
}
// CONFIGS --------------------------------------------
@ -229,6 +238,16 @@ export default class Circle {
return (this._data.config & CIRCLE_CONFIG_OPEN) !== 0
}
/**
* Circle is visible to others
* @readonly
* @memberof Circle
* @returns {boolean}
*/
get isVisible() {
return (this._data.config & CIRCLE_CONFIG_VISIBLE) !== 0
}
/**
* Circle requires invite to be accepted by the member
* @readonly

View File

@ -25,7 +25,6 @@
import { MEMBER_TYPE_USER } from './constants'
import Circle from './circle'
import Vue from 'vue'
export default class Member {
/** @typedef Circle */

View File

@ -41,6 +41,9 @@ const mutations = {
* @param {Circle} circle the circle to add
*/
addCircle(state, circle) {
if (circle.constructor.name !== Circle.name) {
throw new Error('circle must be a Circle type')
}
Vue.set(state.circles, circle.id, circle)
},
@ -51,22 +54,12 @@ const mutations = {
* @param {Circle} circle the circle to delete
*/
deleteCircle(state, circle) {
if (!(circle.id in state.circles)) {
console.warn('Skipping deletion of unknown circle', circle)
}
Vue.delete(state.circles, circle.id)
},
/**
* Rename a circle
*
* @param {Object} state the store mutations
* @param {Object} data destructuring object
* @param {Circle} data.circle the circle to rename
* @param {string} data.newName the new name of the addressbook
*/
renameCircle(state, { circle, newName }) {
circle = state.circles[circle.id]
circle.displayName = newName
},
/**
* Append a list of members to a circle
* and remove duplicates
@ -193,14 +186,21 @@ const actions = {
*
* @param {Object} context the store mutations Current context
* @param {Member} member the member to remove
* @param {boolean} [leave=false] leave the circle instead of removing a member
* @param {boolean} [leave=false] leave the circle instead of removing the member
*/
async deleteMemberFromCircle(context, { member, leave = false }) {
console.info(leave);
const circleId = member.circle.id
const memberId = member.id
if (leave) {
await leaveCircle(circleId)
const circle = await leaveCircle(circleId)
member.circle.updateData(circle)
// If the circle is not visible, we remove it from the list
if (!member.circle.isVisible && !member.circle.isMember) {
await context.commit('deleteCircle', circle)
console.debug('Deleted circle', circleId, memberId)
}
} else {
await deleteMember(circleId, memberId)
}