diff --git a/html/src/app.js b/html/src/app.js
index b5eb0ec6..afd506af 100644
--- a/html/src/app.js
+++ b/html/src/app.js
@@ -7713,16 +7713,25 @@ speechSynthesis.getVoices();
return worldName;
};
- $app.methods.getGroupName = async function (location) {
+ $app.methods.getGroupName = async function (data) {
+ if (!data) {
+ return '';
+ }
var groupName = '';
- try {
+ var groupId = data;
+ if (!data.startsWith('grp_')) {
var L = API.parseLocation(location);
if (L.groupId) {
- var args = await API.getCachedGroup({
- groupId: L.groupId
- });
- groupName = args.ref.name;
+ groupId = L.groupId;
+ } else {
+ return '';
}
+ }
+ try {
+ var args = await API.getCachedGroup({
+ groupId
+ });
+ groupName = args.ref.name;
} catch (err) {}
return groupName;
};
@@ -9531,6 +9540,7 @@ speechSynthesis.getVoices();
'OnPlayerLeft',
'ChangeAvatar',
'ChangeStatus',
+ 'ChangeGroup',
'PortalSpawn',
'DeletedPortal',
'ChatBoxMessage',
@@ -9743,6 +9753,12 @@ speechSynthesis.getVoices();
user.avatarDict,
gameLogDate
);
+ this.parsePhotonGroupChange(
+ id,
+ user.user,
+ user.groupOnNameplate,
+ gameLogDate
+ );
this.parsePhotonAvatar(user.avatarDict);
this.parsePhotonAvatar(user.favatarDict);
var hasInstantiated = false;
@@ -9773,6 +9789,12 @@ speechSynthesis.getVoices();
user.avatarDict,
gameLogDate
);
+ this.parsePhotonGroupChange(
+ id,
+ user.user,
+ user.groupOnNameplate,
+ gameLogDate
+ );
this.parsePhotonAvatar(user.avatarDict);
this.parsePhotonAvatar(user.favatarDict);
var hasInstantiated = false;
@@ -9805,6 +9827,12 @@ speechSynthesis.getVoices();
user.avatarDict,
gameLogDate
);
+ this.parsePhotonGroupChange(
+ id,
+ user.user,
+ user.groupOnNameplate,
+ gameLogDate
+ );
this.parsePhotonAvatar(user.avatarDict);
this.parsePhotonAvatar(user.favatarDict);
var lobbyJointime = this.photonLobbyJointime.get(id);
@@ -9833,6 +9861,12 @@ speechSynthesis.getVoices();
data.Parameters[249].avatarDict,
gameLogDate
);
+ this.parsePhotonGroupChange(
+ data.Parameters[254],
+ data.Parameters[249].user,
+ data.Parameters[249].groupOnNameplate,
+ gameLogDate
+ );
this.parsePhotonAvatar(data.Parameters[249].avatarDict);
this.parsePhotonAvatar(data.Parameters[249].favatarDict);
}
@@ -10564,6 +10598,40 @@ speechSynthesis.getVoices();
this.photonLobbyAvatars.set(user.id, avatar.id);
};
+ $app.methods.parsePhotonGroupChange = async function (
+ photonId,
+ user,
+ groupId,
+ gameLogDate
+ ) {
+ if (
+ typeof user === 'undefined' ||
+ !this.photonLobbyJointime.has(photonId)
+ ) {
+ return;
+ }
+ var {groupOnNameplate} = this.photonLobbyJointime.get(photonId);
+ if (
+ groupOnNameplate !== groupId &&
+ photonId !== this.photonLobbyCurrentUser
+ ) {
+ var groupName = await this.getGroupName(groupId);
+ var previousGroupName = await this.getGroupName(groupOnNameplate);
+ this.addEntryPhotonEvent({
+ photonId,
+ displayName: user.displayName,
+ userId: user.id,
+ text: `ChangeGroup ${groupName}`,
+ type: 'ChangeGroup',
+ created_at: gameLogDate,
+ groupId,
+ groupName,
+ previousGroupId: groupOnNameplate,
+ previousGroupName
+ });
+ }
+ };
+
$app.methods.parsePhotonAvatar = function (avatar) {
if (typeof avatar === 'undefined' || typeof avatar.id === 'undefined') {
console.error('PhotonAvatar: avatar is undefined');
@@ -21129,6 +21197,12 @@ speechSynthesis.getVoices();
user.avatarDict,
dateTime
);
+ this.parsePhotonGroupChange(
+ id,
+ user.user,
+ user.groupOnNameplate,
+ dateTime
+ );
this.parsePhotonAvatar(user.avatarDict);
this.parsePhotonAvatar(user.favatarDict);
var hasInstantiated = false;
diff --git a/html/src/index.pug b/html/src/index.pug
index 76dde4cb..b7e47945 100644
--- a/html/src/index.pug
+++ b/html/src/index.pug
@@ -175,6 +175,13 @@ html
span(v-else) Offline
i.x-user-status(:class="statusClass(scope.row.status)" style="margin-right:5px")
span(v-if="scope.row.statusDescription !== scope.row.previousStatusDescription" v-text="scope.row.statusDescription")
+ template(v-else-if="scope.row.type === 'ChangeGroup'")
+ span.x-link(v-if="scope.row.previousGroupName" v-text="scope.row.previousGroupName" @click="showGroupDialog(scope.row.previousGroupId)" style="margin-right:5px")
+ span.x-link(v-else v-text="scope.row.previousGroupId" @click="showGroupDialog(scope.row.previousGroupId)" style="margin-right:5px")
+ span
+ i.el-icon-right
+ span.x-link(v-if="scope.row.groupName" v-text="scope.row.groupName" @click="showGroupDialog(scope.row.groupId)" style="margin-left:5px")
+ span.x-link(v-else v-text="scope.row.groupId" @click="showGroupDialog(scope.row.groupId)" style="margin-left:5px")
span.x-link(v-else-if="scope.row.type === 'PortalSpawn'" @click="showWorldDialog(scope.row.location, scope.row.shortName)")
location(:location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName" :link="false")
span(v-else-if="scope.row.type === 'ChatBoxMessage'" v-text="scope.row.text")
@@ -229,6 +236,13 @@ html
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class="statusClass(scope.row.status)")
span(v-if="scope.row.statusDescription !== scope.row.previousStatusDescription" v-text="scope.row.statusDescription" style="margin-left:5px")
+ template(v-else-if="scope.row.type === 'ChangeGroup'")
+ span.x-link(v-if="scope.row.previousGroupName" v-text="scope.row.previousGroupName" @click="showGroupDialog(scope.row.previousGroupId)" style="margin-right:5px")
+ span.x-link(v-else v-text="scope.row.previousGroupId" @click="showGroupDialog(scope.row.previousGroupId)" style="margin-right:5px")
+ span
+ i.el-icon-right
+ span.x-link(v-if="scope.row.groupName" v-text="scope.row.groupName" @click="showGroupDialog(scope.row.groupId)" style="margin-left:5px")
+ span.x-link(v-else v-text="scope.row.groupId" @click="showGroupDialog(scope.row.groupId)" style="margin-left:5px")
span.x-link(v-else-if="scope.row.type === 'PortalSpawn'" @click="showWorldDialog(scope.row.location, scope.row.shortName)")
location(:location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName" :link="false")
span(v-else-if="scope.row.type === 'ChatBoxMessage'" v-text="scope.row.text")
@@ -453,7 +467,7 @@ html
template(v-else-if="scope.row.type === 'Event'")
span(v-text="scope.row.data")
template(v-else-if="scope.row.type === 'VideoPlay'")
- span(v-if="scope.row.videoId") {{ scope.row.videoId }}:
+ span(v-if="scope.row.videoId" style="margin-right:5px") {{ scope.row.videoId }}:
span(v-if="scope.row.videoId === 'LSMedia'" v-text="scope.row.videoName")
span.x-link(v-else-if="scope.row.videoName" @click="openExternalLink(scope.row.videoUrl)" v-text="scope.row.videoName")
span.x-link(v-else @click="openExternalLink(scope.row.videoUrl)" v-text="scope.row.videoUrl")
@@ -929,7 +943,7 @@ html
template(v-once #default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('request', scope.row)")
div.options-container
- span.header {{ $t('view.profile.invite__request_response_messages') }}
+ span.header {{ $t('view.profile.invite_request_response_messages') }}
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="inviteRequestResponseMessageTable.visible = true; refreshInviteMessageTable('requestResponse')" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
@@ -2448,7 +2462,7 @@ html
data-tables(v-bind="socialStatusHistoryTable" @row-click="setSocialStatusFromHistory" style="cursor:pointer")
el-table-column(:label="$t('table.social_status.no')" prop="no" width="50")
el-table-column(:label="$t('table.social_status.status')" prop="status")
- el-select(v-model="socialStatusDialog.status" style="dispaly:block;margin-top:10px")
+ el-select(v-model="socialStatusDialog.status" style="display:block;margin-top:10px")
el-option(:label="$t('dialog.user.status.online')" value="active").
#[i.x-user-status.online] {{ $t('dialog.user.status.online') }}
el-option(:label="$t('dialog.user.status.join_me')" value="join me").
@@ -2459,7 +2473,7 @@ html
#[i.x-user-status.busy] {{ $t('dialog.user.status.busy') }}
el-option(v-if="API.currentUser.$isModerator" :label="$t('dialog.user.status.offline')" value="offline").
#[i.x-user-status.offline] {{ $t('dialog.user.status.offline') }}
- el-input(v-model="socialStatusDialog.statusDescription" :placeholder="$t('dialog.social_status.status_placeholder')" maxlength="32" show-word-limit style="dispaly:block;margin-top:10px")
+ el-input(v-model="socialStatusDialog.statusDescription" :placeholder="$t('dialog.social_status.status_placeholder')" maxlength="32" show-word-limit style="display:block;margin-top:10px")
template(#footer)
el-button(type="primary" size="small" :disabled="socialStatusDialog.loading" @click="saveSocialStatus") {{ $t('dialog.social_status.update') }}
@@ -2574,7 +2588,7 @@ html
el-input(type="textarea" v-model="launchOptionsDialog.launchArguments" size="mini" show-word-limit :autosize="{ minRows:2, maxRows:5 }" placeholder="" style="margin-top:10px")
div(style="font-size:12px;margin-top:10px")
| {{ $t('dialog.launch_options.path_override') }}
- el-input(type="textarea" v-model="launchOptionsDialog.vrcLaunchPathOverride" placeholder="C:\\Program Files (x86)\\Steam\\steamapps\\common\\VRChat" :rows="1" style="dispaly:block;margin-top:10px")
+ el-input(type="textarea" v-model="launchOptionsDialog.vrcLaunchPathOverride" placeholder="C:\\Program Files (x86)\\Steam\\steamapps\\common\\VRChat" :rows="1" style="display:block;margin-top:10px")
template(#footer)
div(style="display:flex")
el-button(size="small" @click="openExternalLink('https://docs.vrchat.com/docs/launch-options')") {{ $t('dialog.launch_options.vrchat_docs') }}
@@ -2631,7 +2645,7 @@ html
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="youTubeApiDialog" :visible.sync="youTubeApiDialog.visible" :title="$t('dialog.youtube_api.header')" width="400px")
div(style='font-size:12px;')
| {{ $t('dialog.youtube_api.description') }} #[br]
- el-input(type="textarea" v-model="youTubeApiKey" :placeholder="$t('dialog.youtube_api.placeholder')" maxlength="39" show-word-limit style="dispaly:block;margin-top:10px")
+ el-input(type="textarea" v-model="youTubeApiKey" :placeholder="$t('dialog.youtube_api.placeholder')" maxlength="39" show-word-limit style="display:block;margin-top:10px")
template(#footer)
div(style="display:flex")
el-button(size="small" @click="openExternalLink('https://rapidapi.com/blog/how-to-get-youtube-api-key/')") {{ $t('dialog.youtube_api.guide') }}
diff --git a/html/src/localization/strings/en.json b/html/src/localization/strings/en.json
index f96ff2f0..044858c7 100644
--- a/html/src/localization/strings/en.json
+++ b/html/src/localization/strings/en.json
@@ -74,7 +74,7 @@
"sort_created": "Sort by created"
},
"prev_page": "Prev",
- "next_page": "Nect"
+ "next_page": "Next"
},
"favorite": {
"friends": {
@@ -159,7 +159,7 @@
"invite_messages": "Invite Messages",
"invite_response_messages": "Invite Response Messages",
"invite_request_messages": "Invite Request Messages",
- "invite__request_response_messages": "Invite Request Response Messages",
+ "invite_request_response_messages": "Invite Request Response Messages",
"past_display_names": "Past Display Names",
"config_json": "Config JSON",
"current_user_json": "Current User JSON",
@@ -723,6 +723,9 @@
"friends_only": "Friends Only",
"load_more": "Load more..."
},
+ "gallery": {
+ "header": "Gallery"
+ },
"json": {
"header": "JSON"
}
@@ -733,10 +736,10 @@
"local_favorites": "Local Favorites"
},
"invite": {
- "header": "傳送邀請",
- "select_placeholder": "選擇好友",
- "invite_with_message": "訊息邀請",
- "invite": "邀請"
+ "header": "Invite",
+ "select_placeholder": "Choose Friends",
+ "invite_with_message": "Invite With Message",
+ "invite": "Invite"
},
"social_status": {
"header": "Social Status",
diff --git a/html/src/localization/strings/zh_TW.json b/html/src/localization/strings/zh_TW.json
index 90b7d345..1b47f911 100644
--- a/html/src/localization/strings/zh_TW.json
+++ b/html/src/localization/strings/zh_TW.json
@@ -159,7 +159,7 @@
"invite_messages": "邀請訊息",
"invite_response_messages": "邀請回覆訊息",
"invite_request_messages": "邀請請求訊息",
- "invite__request_response_messages": "邀請請求回覆訊息",
+ "invite_request_response_messages": "邀請請求回覆訊息",
"past_display_names": "過去顯示名稱",
"config_json": "JSON 資料",
"current_user_json": "目前玩家的 JSON 資料",
@@ -733,10 +733,10 @@
"local_favorites": "本地收藏"
},
"invite": {
- "header": "Invite",
- "select_placeholder": "Choose Friends",
- "invite_with_message": "Invite With Message",
- "invite": "Invite"
+ "header": "邀請玩家",
+ "select_placeholder": "選擇好友",
+ "invite_with_message": "邀請訊息",
+ "invite": "邀請"
},
"social_status": {
"header": "社交狀態",
diff --git a/html/src/vr.pug b/html/src/vr.pug
index c1890028..9ca7aa26 100644
--- a/html/src/vr.pug
+++ b/html/src/vr.pug
@@ -69,7 +69,7 @@ html
.detail
span.extra
span.time {{ feed.created_at | formatDate }}
- | 🎵 #[span.name(v-text="feed.displayName" style="margin-right:5px")]
+ | 🎵 #[span.name(v-if="feed.displayName" v-text="feed.displayName" style="margin-right:5px")]
template(v-if="feed.videoName")
| #[span(v-text="feed.videoName")]
template(v-else)
@@ -489,6 +489,9 @@ html
i.el-icon-right
i.x-user-status(:class="statusClass(feed.status)" style="width:20px;height:20px")
span(v-if="feed.statusDescription !== feed.previousStatusDescription" v-text="feed.statusDescription" style="margin-left:10px")
+ template(v-else-if="feed.type === 'ChangeGroup'")
+ span(style="margin-left:10px") ChangeGroup
+ span(v-text="feed.groupName" style="margin-left:10px")
template(v-else-if="feed.type === 'ChatBoxMessage'")
span(style="margin-left:10px") ChatBox
span(v-text="feed.text" style="margin-left:10px;white-space:normal")