diff --git a/VRCX.csproj b/VRCX.csproj
index 92a24f18..0cb5913d 100644
--- a/VRCX.csproj
+++ b/VRCX.csproj
@@ -128,7 +128,7 @@
-
+
diff --git a/html/src/app.js b/html/src/app.js
index 221e597c..fa827ef0 100644
--- a/html/src/app.js
+++ b/html/src/app.js
@@ -29051,6 +29051,98 @@ speechSynthesis.getVoices();
}
});
+ $app.methods.blockGroup = function (groupId) {
+ this.$confirm('Are you sure you want to block this group?', 'Confirm', {
+ confirmButtonText: 'Confirm',
+ cancelButtonText: 'Cancel',
+ type: 'info',
+ callback: (action) => {
+ if (action === 'confirm') {
+ API.blockGroup({
+ groupId
+ });
+ }
+ }
+ });
+ };
+
+ $app.methods.unblockGroup = function (groupId) {
+ this.$confirm(
+ 'Are you sure you want to unblock this group?',
+ 'Confirm',
+ {
+ confirmButtonText: 'Confirm',
+ cancelButtonText: 'Cancel',
+ type: 'info',
+ callback: (action) => {
+ if (action === 'confirm') {
+ API.unblockGroup({
+ groupId,
+ userId: API.currentUser.id
+ });
+ }
+ }
+ }
+ );
+ };
+
+ /**
+ * @param {{
+ groupId: string
+ * }} params
+ * @return { Promise<{json: any, params}> }
+ */
+ API.blockGroup = function (params) {
+ return this.call(`groups/${params.groupId}/block`, {
+ method: 'POST'
+ }).then((json) => {
+ var args = {
+ json,
+ params
+ };
+ this.$emit('GROUP:BLOCK', args);
+ return args;
+ });
+ };
+
+ /**
+ * @param {{
+ groupId: string,
+ userId: string
+ * }} params
+ * @return { Promise<{json: any, params}> }
+ */
+ API.unblockGroup = function (params) {
+ return this.call(`groups/${params.groupId}/members/${params.userId}`, {
+ method: 'DELETE'
+ }).then((json) => {
+ var args = {
+ json,
+ params
+ };
+ this.$emit('GROUP:UNBLOCK', args);
+ return args;
+ });
+ };
+
+ API.$on('GROUP:BLOCK', function (args) {
+ if (
+ $app.groupDialog.visible &&
+ $app.groupDialog.id === args.params.groupId
+ ) {
+ $app.showGroupDialog(args.params.groupId);
+ }
+ });
+
+ API.$on('GROUP:UNBLOCK', function (args) {
+ if (
+ $app.groupDialog.visible &&
+ $app.groupDialog.id === args.params.groupId
+ ) {
+ $app.showGroupDialog(args.params.groupId);
+ }
+ });
+
/**
* @param {{
groupId: string,
@@ -30116,6 +30208,12 @@ speechSynthesis.getVoices();
case 'Leave Group':
this.leaveGroup(D.id);
break;
+ case 'Block Group':
+ this.blockGroup(D.id);
+ break;
+ case 'Unblock Group':
+ this.unblockGroup(D.id);
+ break;
case 'Visibility Everyone':
this.setGroupVisibility(D.id, 'visible');
break;
diff --git a/html/src/index.pug b/html/src/index.pug
index 4cb54309..becb4a81 100644
--- a/html/src/index.pug
+++ b/html/src/index.pug
@@ -236,8 +236,11 @@ html
div(v-for="displayName in userDialog.previousDisplayNames" placement="top")
span(v-text="displayName")
i.el-icon-caret-bottom
- span.dialog-title(v-text="userDialog.ref.displayName" style="margin-left:5px;margin-right:5px")
- span(v-if="userDialog.ref.pronouns" v-text="userDialog.ref.pronouns" style="margin-right:5px;color:#909399;font-family:monospace;font-size:12px")
+ el-popover(placement="top" trigger="click")
+ span.dialog-title(slot="reference" v-text="userDialog.ref.displayName" style="margin-left:5px;margin-right:5px;cursor:pointer")
+ span(style="display:block;text-align:center;font-family:monospace") {{ API.currentUser.username | textToHex }}
+ el-tooltip(v-if="userDialog.ref.pronouns" placement="top" :content="$t('dialog.user.pronouns')" :disabled="hideTooltips")
+ span(v-text="userDialog.ref.pronouns" style="margin-right:5px;color:#909399;font-family:monospace;font-size:12px")
el-tooltip(v-for="item in userDialog.ref.$languages" :key="item.key" placement="top")
template(#content)
span {{ item.value }} ({{ item.key }})
@@ -1009,7 +1012,7 @@ html
el-tooltip(v-if="groupDialog.ref.joinState === 'open'" placement="top" :content="$t('dialog.group.actions.join_group_tooltip')" :disabled="hideTooltips")
el-button(type="default" icon="el-icon-check" circle @click="joinGroup(groupDialog.id)" style="margin-left:5px")
el-dropdown(trigger="click" @command="groupDialogCommand" size="small" style="margin-left:5px")
- el-button(type="default" icon="el-icon-more" circle)
+ el-button(:type="groupDialog.ref.membershipStatus === 'userblocked' ? 'danger' : 'default'" icon="el-icon-more" circle)
el-dropdown-menu(#default="dropdown")
el-dropdown-item(icon="el-icon-refresh" command="Refresh") {{ $t('dialog.group.actions.refresh') }}
template(v-if="groupDialog.inGroup")
@@ -1026,6 +1029,9 @@ html
el-dropdown-item(icon="el-icon-view" command="Visibility Friends") #[i.el-icon-check(v-if="groupDialog.ref.myMember.visibility === 'friends'")] {{ $t('dialog.group.actions.visibility_friends') }}
el-dropdown-item(icon="el-icon-view" command="Visibility Hidden") #[i.el-icon-check(v-if="groupDialog.ref.myMember.visibility === 'hidden'")] {{ $t('dialog.group.actions.visibility_hidden') }}
el-dropdown-item(icon="el-icon-delete" command="Leave Group" style="color:#F56C6C" divided) {{ $t('dialog.group.actions.leave') }}
+ template(v-else)
+ el-dropdown-item(v-if="groupDialog.ref.membershipStatus === 'userblocked'" icon="el-icon-circle-check" command="Unblock Group" style="color:#F56C6C" divided) {{ $t('dialog.group.actions.unblock') }}
+ el-dropdown-item(v-else icon="el-icon-circle-close" command="Block Group" divided) {{ $t('dialog.group.actions.block') }}
el-tabs(ref="groupDialogTabs" @tab-click="groupDialogTabClick")
el-tab-pane(:label="$t('dialog.group.info.header')")
.group-banner-image-info
diff --git a/html/src/localization/en/en.json b/html/src/localization/en/en.json
index 42254583..559030d8 100644
--- a/html/src/localization/en/en.json
+++ b/html/src/localization/en/en.json
@@ -543,9 +543,10 @@
"online": "Online",
"join_me": "Join Me",
"ask_me": "Ask Me",
- "busy": "Do Not Disturb"
+ "busy": "Busy"
},
"previous_display_names": "Previous Display Names:",
+ "pronouns": "Pronouns",
"tags": {
"friend_no": "Friend No.{number}",
"vrchat_team": "VRChat Team"
@@ -837,7 +838,9 @@
"visibility_hidden": "Visibility Hidden",
"create_post": "Create Post",
"moderation_tools": "Moderation Tools",
- "leave": "Leave Group"
+ "leave": "Leave Group",
+ "block": "Block Group",
+ "unblock": "Unblock Group"
},
"info": {
"header": "Info",