refactor: simplify logic for opening onboarding dialogs
This commit is contained in:
@@ -179,21 +179,18 @@
|
||||
|
||||
<!-- Admit Pending Members Dialog Component -->
|
||||
<AdmitPendingMembersDialog
|
||||
:visible="showAdmitPendingDialog"
|
||||
ref="admitPendingMembersDialog"
|
||||
:active-did="activeDid"
|
||||
:api-server="apiServer"
|
||||
:pending-members-data="pendingMembersData"
|
||||
:active-did="activeDid"
|
||||
:api-server="apiServer"
|
||||
@close="closeAdmitPendingDialog"
|
||||
@success="onAdmitPendingSuccess"
|
||||
/>
|
||||
|
||||
<!-- Set Visibility Dialog Component -->
|
||||
<SetBulkVisibilityDialog
|
||||
:visible="showSetVisibilityDialog"
|
||||
:members-data="visibilityDialogMembers"
|
||||
:visible="visibleBulkVisibilityDialog"
|
||||
:active-did="activeDid"
|
||||
:api-server="apiServer"
|
||||
@close="closeSetVisibilityDialog"
|
||||
:members-data="pendingMembersData"
|
||||
@close="closeSetBulkVisibilityDialog"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -217,8 +214,8 @@ import {
|
||||
NOTIFY_CONTINUE_WITHOUT_ADDING,
|
||||
} from "@/constants/notifications";
|
||||
import { SOMEONE_UNNAMED } from "@/constants/entities";
|
||||
import SetBulkVisibilityDialog from "./SetBulkVisibilityDialog.vue";
|
||||
import AdmitPendingMembersDialog from "./AdmitPendingMembersDialog.vue";
|
||||
import SetBulkVisibilityDialog from "./SetBulkVisibilityDialog.vue";
|
||||
|
||||
interface Member {
|
||||
admitted: boolean;
|
||||
@@ -235,8 +232,8 @@ interface DecryptedMember {
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
SetBulkVisibilityDialog,
|
||||
AdmitPendingMembersDialog,
|
||||
SetBulkVisibilityDialog,
|
||||
},
|
||||
mixins: [PlatformServiceMixin],
|
||||
})
|
||||
@@ -255,6 +252,7 @@ export default class MembersList extends Vue {
|
||||
return message;
|
||||
}
|
||||
|
||||
contacts: Array<Contact> = [];
|
||||
decryptedMembers: DecryptedMember[] = [];
|
||||
firstName = "";
|
||||
isLoading = true;
|
||||
@@ -266,32 +264,20 @@ export default class MembersList extends Vue {
|
||||
apiServer = "";
|
||||
|
||||
// Admit Pending Members Dialog state
|
||||
showAdmitPendingDialog = false;
|
||||
pendingMembersData: Array<{
|
||||
did: string;
|
||||
name: string;
|
||||
isContact: boolean;
|
||||
member: { memberId: string };
|
||||
}> = [];
|
||||
admitDialogDismissed = false;
|
||||
isManualRefresh = false;
|
||||
|
||||
// Set Visibility Dialog state
|
||||
showSetVisibilityDialog = false;
|
||||
visibilityDialogMembers: Array<{
|
||||
did: string;
|
||||
name: string;
|
||||
isContact: boolean;
|
||||
member: { memberId: string };
|
||||
}> = [];
|
||||
contacts: Array<Contact> = [];
|
||||
visibleBulkVisibilityDialog = false;
|
||||
|
||||
// Auto-refresh functionality
|
||||
countdownTimer = 10;
|
||||
autoRefreshInterval: NodeJS.Timeout | null = null;
|
||||
|
||||
// Track previous visibility members to detect changes
|
||||
previousVisibilityMembers: string[] = [];
|
||||
lastRefreshTime = 0;
|
||||
previousMemberDidsIgnored: string[] = [];
|
||||
|
||||
/**
|
||||
* Get the unnamed member constant
|
||||
@@ -312,33 +298,18 @@ export default class MembersList extends Vue {
|
||||
|
||||
this.apiServer = settings.apiServer || "";
|
||||
this.firstName = settings.firstName || "";
|
||||
await this.fetchMembers();
|
||||
await this.loadContacts();
|
||||
|
||||
// Start auto-refresh
|
||||
this.startAutoRefresh();
|
||||
|
||||
// Check if we should show the admit pending members dialog first
|
||||
this.checkAndShowAdmitPendingDialog();
|
||||
|
||||
// If no pending members, check for visibility dialog
|
||||
if (!this.showAdmitPendingDialog) {
|
||||
this.checkAndShowVisibilityDialog();
|
||||
}
|
||||
this.refreshData();
|
||||
}
|
||||
|
||||
async refreshData() {
|
||||
async refreshData(showPendingEvenIfAllWereIgnored = false) {
|
||||
// Force refresh both contacts and members
|
||||
await this.loadContacts();
|
||||
this.contacts = await this.$getAllContacts()
|
||||
|
||||
await this.fetchMembers();
|
||||
|
||||
// Check if we should show the admit pending members dialog first
|
||||
this.checkAndShowAdmitPendingDialog();
|
||||
|
||||
// If no pending members, check for visibility dialog
|
||||
if (!this.showAdmitPendingDialog) {
|
||||
this.checkAndShowVisibilityDialog();
|
||||
}
|
||||
this.checkAndShowAdmitPendingDialog(showPendingEvenIfAllWereIgnored);
|
||||
}
|
||||
|
||||
async fetchMembers() {
|
||||
@@ -487,15 +458,11 @@ export default class MembersList extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
async loadContacts() {
|
||||
this.contacts = await this.$getAllContacts();
|
||||
}
|
||||
|
||||
getContactFor(did: string): Contact | undefined {
|
||||
return this.contacts.find((contact) => contact.did === did);
|
||||
}
|
||||
|
||||
getPendingMembers() {
|
||||
getPendingMembers(): { did: string; name: string; isContact: boolean; member: { memberId: string; }; }[] {
|
||||
return this.decryptedMembers
|
||||
.filter((member) => {
|
||||
// Exclude the current user
|
||||
@@ -515,132 +482,64 @@ export default class MembersList extends Vue {
|
||||
}));
|
||||
}
|
||||
|
||||
getMembersForVisibility() {
|
||||
const membersForVisibility = this.decryptedMembers
|
||||
.filter((member) => {
|
||||
// Exclude the current user
|
||||
if (member.did === this.activeDid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const contact = this.getContactFor(member.did);
|
||||
|
||||
// Include members who:
|
||||
// 1. Haven't been added as contacts yet, OR
|
||||
// 2. Are contacts but don't have visibility set (seesMe property)
|
||||
return !contact || !contact.seesMe;
|
||||
})
|
||||
getNonContactMembers(): { did: string; name: string; isContact: boolean; member: { memberId: string; }; }[] {
|
||||
return this.decryptedMembers
|
||||
.filter((member) => !this.getContactFor(member.did))
|
||||
.map((member) => ({
|
||||
did: member.did,
|
||||
name: member.name,
|
||||
isContact: !!this.getContactFor(member.did),
|
||||
isContact: false,
|
||||
member: {
|
||||
memberId: member.member.memberId.toString(),
|
||||
},
|
||||
}));
|
||||
|
||||
// Deduplicate members by DID to prevent duplicate entries
|
||||
const uniqueMembers = membersForVisibility.filter(
|
||||
(member, index, self) =>
|
||||
index === self.findIndex((m) => m.did === member.did),
|
||||
);
|
||||
|
||||
return uniqueMembers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we should show the visibility dialog
|
||||
* Returns true if there are members for visibility and either:
|
||||
* - This is the first time (no previous members tracked), OR
|
||||
* - New members have been added since last check (not removed), OR
|
||||
* - This is a manual refresh (isManualRefresh flag is set)
|
||||
*/
|
||||
shouldShowVisibilityDialog(): boolean {
|
||||
// Only show for members who can see other members (i.e., they are in the decrypted members list)
|
||||
const currentUserMember = this.decryptedMembers.find(
|
||||
(member) => member.did === this.activeDid,
|
||||
);
|
||||
|
||||
// If the current user is not in the decrypted members list, they can't see anyone
|
||||
if (!currentUserMember) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const currentMembers = this.getMembersForVisibility();
|
||||
|
||||
if (currentMembers.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If no previous members tracked, show dialog
|
||||
if (this.previousVisibilityMembers.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If this is a manual refresh, always show dialog if there are members
|
||||
if (this.isManualRefresh) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if new members have been added (not just any change)
|
||||
const currentMemberIds = currentMembers.map((m) => m.did);
|
||||
const previousMemberIds = this.previousVisibilityMembers;
|
||||
|
||||
// Find new members (members in current but not in previous)
|
||||
const newMembers = currentMemberIds.filter(
|
||||
(id) => !previousMemberIds.includes(id),
|
||||
);
|
||||
|
||||
// Only show dialog if there are new members added
|
||||
return newMembers.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the tracking of previous visibility members
|
||||
*/
|
||||
updatePreviousVisibilityMembers() {
|
||||
const currentMembers = this.getMembersForVisibility();
|
||||
this.previousVisibilityMembers = currentMembers.map((m) => m.did);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we should show the admit pending members dialog
|
||||
*/
|
||||
shouldShowAdmitPendingDialog(): boolean {
|
||||
// Don't show if already dismissed
|
||||
if (this.admitDialogDismissed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only show for the organizer of the meeting
|
||||
if (!this.isOrganizer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const pendingMembers = this.getPendingMembers();
|
||||
return pendingMembers.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the admit pending members dialog if conditions are met
|
||||
*/
|
||||
checkAndShowAdmitPendingDialog() {
|
||||
if (this.shouldShowAdmitPendingDialog()) {
|
||||
this.showAdmitPendingDialogMethod();
|
||||
checkAndShowAdmitPendingDialog(showPendingEvenIfAllWereIgnored = false) {
|
||||
const pendingMembers =
|
||||
this.isOrganizer ? this.getPendingMembers() : this.getNonContactMembers();
|
||||
if (pendingMembers.length === 0) {
|
||||
this.startAutoRefresh();
|
||||
return;
|
||||
}
|
||||
if (!showPendingEvenIfAllWereIgnored) {
|
||||
// only show if there are pending members that have not been ignored
|
||||
const pendingMembersNotIgnored =
|
||||
pendingMembers.filter(
|
||||
(member) => !this.previousMemberDidsIgnored.includes(member.did)
|
||||
);
|
||||
if (pendingMembersNotIgnored.length === 0) {
|
||||
this.startAutoRefresh();
|
||||
// everyone waiting has been ignored
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.stopAutoRefresh();
|
||||
this.pendingMembersData = pendingMembers;
|
||||
if (this.isOrganizer) {
|
||||
(this.$refs.admitPendingMembersDialog as AdmitPendingMembersDialog).open();
|
||||
} else {
|
||||
// Ensure dialog state is false when no pending members
|
||||
this.showAdmitPendingDialog = false;
|
||||
this.visibleBulkVisibilityDialog = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the visibility dialog if conditions are met
|
||||
*/
|
||||
checkAndShowVisibilityDialog() {
|
||||
if (this.shouldShowVisibilityDialog()) {
|
||||
this.showSetBulkVisibilityDialog();
|
||||
}
|
||||
this.updatePreviousVisibilityMembers();
|
||||
// Admit Pending Members Dialog methods
|
||||
async closeAdmitPendingDialog(result: { notSelectedMemberDids: string[] } | undefined) {
|
||||
this.pendingMembersData = [];
|
||||
this.previousMemberDidsIgnored = result?.notSelectedMemberDids || [];
|
||||
|
||||
await this.refreshData();
|
||||
}
|
||||
|
||||
async closeSetBulkVisibilityDialog(result: { notSelectedMemberDids: string[] } | undefined) {
|
||||
this.visibleBulkVisibilityDialog = false;
|
||||
this.pendingMembersData = [];
|
||||
this.previousMemberDidsIgnored = result?.notSelectedMemberDids || [];
|
||||
|
||||
await this.refreshData();
|
||||
}
|
||||
|
||||
checkWhetherContactBeforeAdmitting(decrMember: DecryptedMember) {
|
||||
@@ -781,51 +680,19 @@ export default class MembersList extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
showAdmitPendingDialogMethod() {
|
||||
// Filter members to show only pending (non-admitted) members
|
||||
const pendingMembers = this.getPendingMembers();
|
||||
|
||||
// Only show dialog if there are pending members
|
||||
if (pendingMembers.length === 0) {
|
||||
this.showAdmitPendingDialog = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Pause auto-refresh when dialog opens
|
||||
this.stopAutoRefresh();
|
||||
|
||||
// Open the dialog directly
|
||||
this.pendingMembersData = pendingMembers;
|
||||
this.showAdmitPendingDialog = true;
|
||||
}
|
||||
|
||||
showSetBulkVisibilityDialog() {
|
||||
// Filter members to show only those who need visibility set
|
||||
const membersForVisibility = this.getMembersForVisibility();
|
||||
|
||||
// Pause auto-refresh when dialog opens
|
||||
this.stopAutoRefresh();
|
||||
|
||||
// Open the dialog directly
|
||||
this.visibilityDialogMembers = membersForVisibility;
|
||||
this.showSetVisibilityDialog = true;
|
||||
|
||||
// Reset manual refresh flag after dialog is shown
|
||||
this.isManualRefresh = false;
|
||||
}
|
||||
|
||||
startAutoRefresh() {
|
||||
let lastRefreshTime = Date.now();
|
||||
this.lastRefreshTime = Date.now();
|
||||
this.countdownTimer = 10;
|
||||
|
||||
this.autoRefreshInterval = setInterval(() => {
|
||||
const now = Date.now();
|
||||
const timeSinceLastRefresh = (now - lastRefreshTime) / 1000;
|
||||
const timeSinceLastRefresh = (now - this.lastRefreshTime) / 1000;
|
||||
|
||||
if (timeSinceLastRefresh >= 10) {
|
||||
// Time to refresh
|
||||
this.refreshData();
|
||||
lastRefreshTime = now;
|
||||
this.lastRefreshTime = now;
|
||||
this.countdownTimer = 10;
|
||||
} else {
|
||||
// Update countdown
|
||||
@@ -851,68 +718,8 @@ export default class MembersList extends Vue {
|
||||
this.autoRefreshInterval = null;
|
||||
}
|
||||
|
||||
// Set manual refresh flag
|
||||
this.isManualRefresh = true;
|
||||
// Reset the dismissed flag on manual refresh
|
||||
this.admitDialogDismissed = false;
|
||||
|
||||
// Trigger immediate refresh
|
||||
await this.refreshData();
|
||||
|
||||
// Only start auto-refresh if no dialogs are showing
|
||||
if (!this.showAdmitPendingDialog && !this.showSetVisibilityDialog) {
|
||||
this.startAutoRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
// Admit Pending Members Dialog methods
|
||||
async closeAdmitPendingDialog() {
|
||||
this.showAdmitPendingDialog = false;
|
||||
this.pendingMembersData = [];
|
||||
this.admitDialogDismissed = true;
|
||||
|
||||
// Handle manual refresh flow
|
||||
if (this.isManualRefresh) {
|
||||
await this.handleManualRefreshFlow();
|
||||
this.isManualRefresh = false;
|
||||
} else {
|
||||
// Normal flow: refresh data and resume auto-refresh
|
||||
this.refreshData();
|
||||
this.startAutoRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
async handleManualRefreshFlow() {
|
||||
// Refresh data to reflect any changes made in the admit dialog
|
||||
await this.refreshData();
|
||||
|
||||
// Use the same logic as normal flow to check for visibility dialog
|
||||
this.checkAndShowVisibilityDialog();
|
||||
|
||||
// If no visibility dialog was shown, resume auto-refresh
|
||||
if (!this.showSetVisibilityDialog) {
|
||||
this.startAutoRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
async onAdmitPendingSuccess(_result: {
|
||||
admittedCount: number;
|
||||
contactAddedCount: number;
|
||||
visibilitySetCount: number;
|
||||
}) {
|
||||
// After admitting pending members, close the admit dialog
|
||||
// The visibility dialog will be handled by the closeAdmitPendingDialog flow
|
||||
await this.closeAdmitPendingDialog();
|
||||
}
|
||||
|
||||
// Set Visibility Dialog methods
|
||||
closeSetVisibilityDialog() {
|
||||
this.showSetVisibilityDialog = false;
|
||||
this.visibilityDialogMembers = [];
|
||||
// Refresh data when dialog is closed to reflect any changes made
|
||||
this.refreshData();
|
||||
// Resume auto-refresh when dialog is closed
|
||||
this.startAutoRefresh();
|
||||
await this.refreshData(true);
|
||||
}
|
||||
|
||||
beforeDestroy() {
|
||||
|
||||
Reference in New Issue
Block a user