mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-27 18:53:47 +02:00
refactor dialog commands func
This commit is contained in:
@@ -413,6 +413,7 @@
|
||||
|
||||
import DialogJsonTab from '../DialogJsonTab.vue';
|
||||
import GroupDialogInfoTab from './GroupDialogInfoTab.vue';
|
||||
import { useGroupDialogCommands } from './useGroupDialogCommands';
|
||||
import GroupDialogMembersTab from './GroupDialogMembersTab.vue';
|
||||
import GroupDialogPhotosTab from './GroupDialogPhotosTab.vue';
|
||||
import GroupDialogPostsTab from './GroupDialogPostsTab.vue';
|
||||
@@ -444,6 +445,28 @@
|
||||
|
||||
const { showFullscreenImageDialog } = useGalleryStore();
|
||||
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, {
|
||||
t,
|
||||
modalStore,
|
||||
currentUser,
|
||||
showGroupDialog,
|
||||
leaveGroupPrompt,
|
||||
setGroupVisibility,
|
||||
setGroupSubscription,
|
||||
showGroupMemberModerationDialog,
|
||||
showInviteGroupDialog: (groupId, userId) => {
|
||||
if (groupId) {
|
||||
inviteGroupDialog.value.groupId = groupId;
|
||||
}
|
||||
if (userId) {
|
||||
inviteGroupDialog.value.userId = userId;
|
||||
}
|
||||
inviteGroupDialog.value.visible = true;
|
||||
},
|
||||
showGroupPostEditDialog,
|
||||
groupRequest
|
||||
});
|
||||
|
||||
const groupDialogTabCurrentName = ref('0');
|
||||
const treeData = ref({});
|
||||
const membersTabRef = ref(null);
|
||||
@@ -474,20 +497,7 @@
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param groupId
|
||||
* @param userId
|
||||
*/
|
||||
function showInviteGroupDialog(groupId, userId) {
|
||||
if (groupId) {
|
||||
inviteGroupDialog.value.groupId = groupId;
|
||||
}
|
||||
if (userId) {
|
||||
inviteGroupDialog.value.userId = userId;
|
||||
}
|
||||
inviteGroupDialog.value.visible = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -594,109 +604,7 @@
|
||||
* @param gallery
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param command
|
||||
*/
|
||||
function groupDialogCommand(command) {
|
||||
const D = groupDialog.value;
|
||||
if (D.visible === false) {
|
||||
return;
|
||||
}
|
||||
switch (command) {
|
||||
case 'Share':
|
||||
copyToClipboard(groupDialog.value.ref.$url);
|
||||
break;
|
||||
case 'Create Post':
|
||||
showGroupPostEditDialog(groupDialog.value.id, null);
|
||||
break;
|
||||
case 'Moderation Tools':
|
||||
showGroupMemberModerationDialog(groupDialog.value.id);
|
||||
break;
|
||||
case 'Invite To Group':
|
||||
showInviteGroupDialog(D.id, '');
|
||||
break;
|
||||
case 'Refresh':
|
||||
const groupId = D.id;
|
||||
showGroupDialog(groupId, { forceRefresh: true });
|
||||
break;
|
||||
case 'Leave Group':
|
||||
leaveGroupPrompt(D.id);
|
||||
break;
|
||||
case 'Block Group':
|
||||
blockGroup(D.id);
|
||||
break;
|
||||
case 'Unblock Group':
|
||||
unblockGroup(D.id);
|
||||
break;
|
||||
case 'Visibility Everyone':
|
||||
setGroupVisibility(D.id, 'visible');
|
||||
break;
|
||||
case 'Visibility Friends':
|
||||
setGroupVisibility(D.id, 'friends');
|
||||
break;
|
||||
case 'Visibility Hidden':
|
||||
setGroupVisibility(D.id, 'hidden');
|
||||
break;
|
||||
case 'Subscribe To Announcements':
|
||||
setGroupSubscription(D.id, true);
|
||||
break;
|
||||
case 'Unsubscribe To Announcements':
|
||||
setGroupSubscription(D.id, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param groupId
|
||||
*/
|
||||
function blockGroup(groupId) {
|
||||
modalStore
|
||||
.confirm({
|
||||
description: t('confirm.block_group'),
|
||||
title: t('confirm.title')
|
||||
})
|
||||
.then(({ ok }) => {
|
||||
if (!ok) return;
|
||||
groupRequest
|
||||
.blockGroup({
|
||||
groupId
|
||||
})
|
||||
.then((args) => {
|
||||
if (groupDialog.value.visible && groupDialog.value.id === args.params.groupId) {
|
||||
showGroupDialog(args.params.groupId);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param groupId
|
||||
*/
|
||||
function unblockGroup(groupId) {
|
||||
modalStore
|
||||
.confirm({
|
||||
description: t('confirm.unblock_group'),
|
||||
title: t('confirm.title')
|
||||
})
|
||||
.then(({ ok }) => {
|
||||
if (!ok) return;
|
||||
groupRequest
|
||||
.unblockGroup({
|
||||
groupId,
|
||||
userId: currentUser.value.id
|
||||
})
|
||||
.then((args) => {
|
||||
if (groupDialog.value.visible && groupDialog.value.id === args.params.groupId) {
|
||||
showGroupDialog(args.params.groupId);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { useGroupDialogCommands } from '../useGroupDialogCommands';
|
||||
|
||||
vi.mock('../../../../shared/utils', () => ({
|
||||
copyToClipboard: vi.fn()
|
||||
}));
|
||||
|
||||
const { copyToClipboard } = await import('../../../../shared/utils');
|
||||
|
||||
function createGroupDialog(overrides = {}) {
|
||||
return ref({
|
||||
visible: true,
|
||||
id: 'grp_123',
|
||||
ref: {
|
||||
$url: 'https://vrchat.com/home/group/grp_123'
|
||||
},
|
||||
...overrides
|
||||
});
|
||||
}
|
||||
|
||||
function createDeps(overrides = {}) {
|
||||
return {
|
||||
t: vi.fn((key) => key),
|
||||
modalStore: {
|
||||
confirm: vi.fn().mockResolvedValue({ ok: true })
|
||||
},
|
||||
currentUser: ref({ id: 'usr_current' }),
|
||||
showGroupDialog: vi.fn(),
|
||||
leaveGroupPrompt: vi.fn(),
|
||||
setGroupVisibility: vi.fn(),
|
||||
setGroupSubscription: vi.fn(),
|
||||
showGroupMemberModerationDialog: vi.fn(),
|
||||
showInviteGroupDialog: vi.fn(),
|
||||
showGroupPostEditDialog: vi.fn(),
|
||||
groupRequest: {
|
||||
blockGroup: vi.fn().mockResolvedValue({
|
||||
params: { groupId: 'grp_123' }
|
||||
}),
|
||||
unblockGroup: vi.fn().mockResolvedValue({
|
||||
params: { groupId: 'grp_123' }
|
||||
})
|
||||
},
|
||||
...overrides
|
||||
};
|
||||
}
|
||||
|
||||
describe('useGroupDialogCommands', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('returns early when dialog is not visible', () => {
|
||||
const groupDialog = createGroupDialog({ visible: false });
|
||||
const deps = createDeps();
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
|
||||
groupDialogCommand('Refresh');
|
||||
expect(deps.showGroupDialog).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Share copies group URL', () => {
|
||||
const groupDialog = createGroupDialog();
|
||||
const deps = createDeps();
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
|
||||
groupDialogCommand('Share');
|
||||
expect(copyToClipboard).toHaveBeenCalledWith(
|
||||
'https://vrchat.com/home/group/grp_123'
|
||||
);
|
||||
});
|
||||
|
||||
it('Invite To Group dispatches invite callback', () => {
|
||||
const groupDialog = createGroupDialog();
|
||||
const deps = createDeps();
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
|
||||
groupDialogCommand('Invite To Group');
|
||||
expect(deps.showInviteGroupDialog).toHaveBeenCalledWith('grp_123', '');
|
||||
});
|
||||
|
||||
it('Refresh calls showGroupDialog with forceRefresh', () => {
|
||||
const groupDialog = createGroupDialog();
|
||||
const deps = createDeps();
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
|
||||
groupDialogCommand('Refresh');
|
||||
expect(deps.showGroupDialog).toHaveBeenCalledWith('grp_123', {
|
||||
forceRefresh: true
|
||||
});
|
||||
});
|
||||
|
||||
it('Block Group confirms and calls blockGroup', async () => {
|
||||
const groupDialog = createGroupDialog();
|
||||
const deps = createDeps();
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
|
||||
groupDialogCommand('Block Group');
|
||||
await vi.waitFor(() => {
|
||||
expect(deps.modalStore.confirm).toHaveBeenCalled();
|
||||
expect(deps.groupRequest.blockGroup).toHaveBeenCalledWith({
|
||||
groupId: 'grp_123'
|
||||
});
|
||||
expect(deps.showGroupDialog).toHaveBeenCalledWith('grp_123');
|
||||
});
|
||||
});
|
||||
|
||||
it('Unblock Group confirms and calls unblockGroup', async () => {
|
||||
const groupDialog = createGroupDialog();
|
||||
const deps = createDeps();
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
|
||||
groupDialogCommand('Unblock Group');
|
||||
await vi.waitFor(() => {
|
||||
expect(deps.modalStore.confirm).toHaveBeenCalled();
|
||||
expect(deps.groupRequest.unblockGroup).toHaveBeenCalledWith({
|
||||
groupId: 'grp_123',
|
||||
userId: 'usr_current'
|
||||
});
|
||||
expect(deps.showGroupDialog).toHaveBeenCalledWith('grp_123');
|
||||
});
|
||||
});
|
||||
|
||||
it('does not run confirmed action when confirmation is cancelled', async () => {
|
||||
const groupDialog = createGroupDialog();
|
||||
const deps = createDeps({
|
||||
modalStore: {
|
||||
confirm: vi.fn().mockResolvedValue({ ok: false })
|
||||
}
|
||||
});
|
||||
const { groupDialogCommand } = useGroupDialogCommands(groupDialog, deps);
|
||||
|
||||
groupDialogCommand('Block Group');
|
||||
await vi.waitFor(() => {
|
||||
expect(deps.modalStore.confirm).toHaveBeenCalled();
|
||||
});
|
||||
expect(deps.groupRequest.blockGroup).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
164
src/components/dialogs/GroupDialog/useGroupDialogCommands.js
Normal file
164
src/components/dialogs/GroupDialog/useGroupDialogCommands.js
Normal file
@@ -0,0 +1,164 @@
|
||||
import { copyToClipboard } from '../../../shared/utils';
|
||||
|
||||
/**
|
||||
* Composable for GroupDialog command dispatch.
|
||||
* Uses a command map pattern consistent with Avatar/World/User dialogs.
|
||||
* @param {import('vue').Ref} groupDialog - reactive ref to the group dialog state
|
||||
* @param {object} deps - external dependencies
|
||||
* @param deps.t
|
||||
* @param deps.modalStore
|
||||
* @param deps.currentUser
|
||||
* @param deps.showGroupDialog
|
||||
* @param deps.leaveGroupPrompt
|
||||
* @param deps.setGroupVisibility
|
||||
* @param deps.setGroupSubscription
|
||||
* @param deps.showGroupMemberModerationDialog
|
||||
* @param deps.showInviteGroupDialog
|
||||
* @param deps.showGroupPostEditDialog
|
||||
* @param deps.groupRequest
|
||||
* @returns {object} command composable API
|
||||
*/
|
||||
export function useGroupDialogCommands(
|
||||
groupDialog,
|
||||
{
|
||||
t,
|
||||
modalStore,
|
||||
currentUser,
|
||||
showGroupDialog,
|
||||
leaveGroupPrompt,
|
||||
setGroupVisibility,
|
||||
setGroupSubscription,
|
||||
showGroupMemberModerationDialog,
|
||||
showInviteGroupDialog,
|
||||
showGroupPostEditDialog,
|
||||
groupRequest
|
||||
}
|
||||
) {
|
||||
// --- Command map ---
|
||||
// Direct commands: function
|
||||
// Confirmed commands: { confirm: () => ({title, description, ...}), handler: fn }
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function buildCommandMap() {
|
||||
const D = () => groupDialog.value;
|
||||
|
||||
return {
|
||||
// --- Direct commands ---
|
||||
Share: () => {
|
||||
copyToClipboard(D().ref.$url);
|
||||
},
|
||||
'Create Post': () => {
|
||||
showGroupPostEditDialog(D().id, null);
|
||||
},
|
||||
'Moderation Tools': () => {
|
||||
showGroupMemberModerationDialog(D().id);
|
||||
},
|
||||
'Invite To Group': () => {
|
||||
showInviteGroupDialog(D().id, '');
|
||||
},
|
||||
Refresh: () => {
|
||||
showGroupDialog(D().id, { forceRefresh: true });
|
||||
},
|
||||
'Leave Group': () => {
|
||||
leaveGroupPrompt(D().id);
|
||||
},
|
||||
'Visibility Everyone': () => {
|
||||
setGroupVisibility(D().id, 'visible');
|
||||
},
|
||||
'Visibility Friends': () => {
|
||||
setGroupVisibility(D().id, 'friends');
|
||||
},
|
||||
'Visibility Hidden': () => {
|
||||
setGroupVisibility(D().id, 'hidden');
|
||||
},
|
||||
'Subscribe To Announcements': () => {
|
||||
setGroupSubscription(D().id, true);
|
||||
},
|
||||
'Unsubscribe To Announcements': () => {
|
||||
setGroupSubscription(D().id, false);
|
||||
},
|
||||
|
||||
// --- Confirmed commands ---
|
||||
'Block Group': {
|
||||
confirm: () => ({
|
||||
title: t('confirm.title'),
|
||||
description: t('confirm.block_group')
|
||||
}),
|
||||
handler: (id) => {
|
||||
groupRequest.blockGroup({ groupId: id }).then((args) => {
|
||||
if (
|
||||
groupDialog.value.visible &&
|
||||
groupDialog.value.id === args.params.groupId
|
||||
) {
|
||||
showGroupDialog(args.params.groupId);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
'Unblock Group': {
|
||||
confirm: () => ({
|
||||
title: t('confirm.title'),
|
||||
description: t('confirm.unblock_group')
|
||||
}),
|
||||
handler: (id) => {
|
||||
groupRequest
|
||||
.unblockGroup({
|
||||
groupId: id,
|
||||
userId: currentUser.value.id
|
||||
})
|
||||
.then((args) => {
|
||||
if (
|
||||
groupDialog.value.visible &&
|
||||
groupDialog.value.id === args.params.groupId
|
||||
) {
|
||||
showGroupDialog(args.params.groupId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const commandMap = buildCommandMap();
|
||||
|
||||
/**
|
||||
* Dispatch a group dialog command.
|
||||
* @param {string} command
|
||||
*/
|
||||
function groupDialogCommand(command) {
|
||||
const D = groupDialog.value;
|
||||
if (D.visible === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
const entry = commandMap[command];
|
||||
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Direct function
|
||||
if (typeof entry === 'function') {
|
||||
entry();
|
||||
return;
|
||||
}
|
||||
|
||||
// Confirmed command
|
||||
if (entry.confirm) {
|
||||
modalStore
|
||||
.confirm(entry.confirm())
|
||||
.then(({ ok }) => {
|
||||
if (ok) {
|
||||
entry.handler(D.id);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
groupDialogCommand
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user