diff --git a/src/api/avatar.js b/src/api/avatar.js index 9a033b34..419bf5bc 100644 --- a/src/api/avatar.js +++ b/src/api/avatar.js @@ -49,7 +49,7 @@ const avatarReq = { }); }, /** - * @param {{ id: string, releaseStatus?: 'public' | 'private', name?: string, description?: string }} params + * @param {{ id: string, releaseStatus?: 'public' | 'private', name?: string, description?: string,tags?: string[] }} params * @returns {Promise<{json: any, params}>} */ saveAvatar(params) { diff --git a/src/api/favorite.js b/src/api/favorite.js index 78ed36e7..7f61ab47 100644 --- a/src/api/favorite.js +++ b/src/api/favorite.js @@ -34,12 +34,7 @@ const favoriteReq = { }, /** - * @param {{ - * type: string, - * favoriteId: string (objectId), - * tags: string - * }} params - * @return { Promise<{json: any, params}> } + * @type {import('../types/favorite').addFavorite} */ addFavorite(params) { return request('favorites', { diff --git a/src/api/group.js b/src/api/group.js index a5c0dbb2..601d2800 100644 --- a/src/api/group.js +++ b/src/api/group.js @@ -75,7 +75,7 @@ const groupReq = { /** * * @param {{ groupId: string }} params - * @return { Promise<{json: any, params}> } + * @return { Promise<{json: any, ref: any, cache?: boolean, params}> } */ getCachedGroup(params) { const groupStore = useGroupStore(); diff --git a/src/api/instance.js b/src/api/instance.js index 5deb5aa2..ac04730b 100644 --- a/src/api/instance.js +++ b/src/api/instance.js @@ -52,8 +52,7 @@ const instanceReq = { }, /** - * @param {{ worldId: string, instanceId: string, shortName: string }} instance - * @returns {Promise<{instance, json: T, params: {}}>} + * @type {import('../types/instance').getInstanceShortName} */ getInstanceShortName(instance) { const params = {}; diff --git a/src/api/misc.js b/src/api/misc.js index 8d3b900c..de8996f2 100644 --- a/src/api/misc.js +++ b/src/api/misc.js @@ -59,7 +59,8 @@ const miscReq = { /** * @param {{ * fileId: string, - * version: number + * version: number, + * variant: string * }} params * @return { Promise<{json: any, params}> } */ diff --git a/src/api/world.js b/src/api/world.js index fff55ac7..cab5028f 100644 --- a/src/api/world.js +++ b/src/api/world.js @@ -3,8 +3,7 @@ import { useWorldStore } from '../stores'; const worldReq = { /** - * @param {{worldId: string}} params - * @returns {Promise<{json: any, params}>} + * @type {import('../types/world').getWorld} */ getWorld(params) { const worldStore = useWorldStore(); @@ -22,7 +21,7 @@ const worldReq = { /** * @param {{worldId: string}} params - * @returns {Promise<{json: any, params}>} + * @returns {Promise<{json: any, ref: any, cache?: boolean, params}>} */ getCachedWorld(params) { const worldStore = useWorldStore(); diff --git a/src/components/dialogs/AvatarDialog/AvatarDialog.vue b/src/components/dialogs/AvatarDialog/AvatarDialog.vue index 05800c6f..094c0401 100644 --- a/src/components/dialogs/AvatarDialog/AvatarDialog.vue +++ b/src/components/dialogs/AvatarDialog/AvatarDialog.vue @@ -274,7 +274,7 @@ :type="avatarDialog.isBlocked ? 'danger' : 'default'" icon="el-icon-more" circle> - + {{ t('dialog.avatar.actions.refresh') }} @@ -481,7 +481,7 @@ icon="el-icon-s-order" size="mini" circle> - + {{ t('dialog.avatar.info.copy_id') }} @@ -793,7 +793,7 @@ showSetAvatarTagsDialog(D.id); break; case 'Change Styles and Author Tags': - showSetAvatarStylesDialog(D.id); + showSetAvatarStylesDialog(); break; case 'Download Unity Package': openExternalLink(replaceVrcPackageUrl(avatarDialog.value.ref.unityPackageUrl)); @@ -1126,8 +1126,8 @@ }); return; } - miscRequest.getFileAnalysis({ fileId, version, variant, avatarId }).then((args) => { - if (!avatarDialog.value.visible || avatarDialog.value.id !== args.params.avatarId) { + miscRequest.getFileAnalysis({ fileId, version, variant }).then((args) => { + if (!avatarDialog.value.visible || avatarDialog.value.id !== avatarId) { return; } const ref = args.json; @@ -1242,8 +1242,9 @@ function onFileChangeAvatarGallery(e) { const clearFile = function () { - if (document.querySelector('#AvatarGalleryUploadButton')) { - document.querySelector('#AvatarGalleryUploadButton').value = ''; + const fileInput = /** @type {HTMLInputElement} */ (document.querySelector('#AvatarGalleryUploadButton')); + if (fileInput) { + fileInput.value = ''; } }; const files = e.target.files || e.dataTransfer.files; @@ -1270,16 +1271,16 @@ const r = new FileReader(); r.onload = function () { avatarDialog.value.galleryLoading = true; - const base64Body = btoa(r.result); + const base64Body = btoa(r.result.toString()); avatarRequest .uploadAvatarGalleryImage(base64Body, avatarDialog.value.id) - .then((args) => { + .then(async (args) => { $message({ message: t('message.avatar_gallery.uploaded'), type: 'success' }); console.log(args); - avatarDialog.value.galleryImages = getAvatarGallery(avatarDialog.value.id); + avatarDialog.value.galleryImages = await getAvatarGallery(avatarDialog.value.id); return args; }) .finally(() => { @@ -1323,12 +1324,12 @@ } else { moveArrayItem(fileIds, index, index + 1); } - avatarRequest.setAvatarGalleryOrder(fileIds).then((args) => { + avatarRequest.setAvatarGalleryOrder(fileIds).then(async (args) => { $message({ message: t('message.avatar_gallery.reordered'), type: 'success' }); - avatarDialog.value.galleryImages = getAvatarGallery(avatarDialog.value.id); + avatarDialog.value.galleryImages = await getAvatarGallery(avatarDialog.value.id); return args; }); } diff --git a/src/components/dialogs/AvatarDialog/ChangeAvatarImageDialog.vue b/src/components/dialogs/AvatarDialog/ChangeAvatarImageDialog.vue index 1573a30b..0138abae 100644 --- a/src/components/dialogs/AvatarDialog/ChangeAvatarImageDialog.vue +++ b/src/components/dialogs/AvatarDialog/ChangeAvatarImageDialog.vue @@ -113,8 +113,9 @@ function onFileChangeAvatarImage(e) { const clearFile = function () { - if (document.querySelector('#AvatarImageUploadButton')) { - document.querySelector('#AvatarImageUploadButton').value = ''; + const fileInput = /** @type{HTMLInputElement} */ (document.querySelector('#AvatarImageUploadButton')); + if (fileInput) { + fileInput.value = ''; } }; const files = e.target.files || e.dataTransfer.files; @@ -145,10 +146,10 @@ const r = new FileReader(); r.onload = async function (file) { try { - const base64File = await resizeImageToFitLimits(btoa(r.result)); + const base64File = await resizeImageToFitLimits(btoa(r.result.toString())); // 10MB const fileMd5 = await genMd5(base64File); - const fileSizeInBytes = parseInt(file.total, 10); + const fileSizeInBytes = parseInt(file.total.toString(), 10); const base64SignatureFile = await genSig(base64File); const signatureMd5 = await genMd5(base64SignatureFile); const signatureSizeInBytes = parseInt(await genLength(base64SignatureFile), 10); @@ -237,7 +238,7 @@ if (json.status !== 200) { changeAvatarImageDialogLoading.value = false; - $throw('Avatar image upload failed', json, params.url); + $throw(json.status, 'Avatar image upload failed', params.url); } const args = { json, @@ -290,7 +291,7 @@ if (json.status !== 200) { changeAvatarImageDialogLoading.value = false; - $throw('Avatar image upload failed', json, params.url); + $throw(json.status, 'Avatar image upload failed', params.url); } const args = { json, diff --git a/src/components/dialogs/GalleryDialog.vue b/src/components/dialogs/GalleryDialog.vue index c8353419..1003ffda 100644 --- a/src/components/dialogs/GalleryDialog.vue +++ b/src/components/dialogs/GalleryDialog.vue @@ -557,8 +557,9 @@ function onFileChangeGallery(e) { const clearFile = function () { - if (document.querySelector('#GalleryUploadButton')) { - document.querySelector('#GalleryUploadButton').value = ''; + const fileInput = /** @type {HTMLInputElement} */ (document.querySelector('#GalleryUploadButton')); + if (fileInput) { + fileInput.value = ''; } }; const files = e.target.files || e.dataTransfer.files; @@ -584,7 +585,7 @@ } const r = new FileReader(); r.onload = function () { - const base64Body = btoa(r.result); + const base64Body = btoa(r.result.toString()); vrcPlusImageRequest.uploadGalleryImage(base64Body).then((args) => { handleGalleryImageAdd(args); proxy.$message({ @@ -655,8 +656,9 @@ function onFileChangeVRCPlusIcon(e) { const clearFile = function () { - if (document.querySelector('#VRCPlusIconUploadButton')) { - document.querySelector('#VRCPlusIconUploadButton').value = ''; + const fileInput = /** @type {HTMLInputElement} */ (document.querySelector('#VRCPlusIconUploadButton')); + if (fileInput) { + fileInput.value = ''; } }; const files = e.target.files || e.dataTransfer.files; @@ -682,7 +684,7 @@ } const r = new FileReader(); r.onload = function () { - const base64Body = btoa(r.result); + const base64Body = btoa(r.result.toString()); vrcPlusIconRequest.uploadVRCPlusIcon(base64Body).then((args) => { if (Object.keys(VRCPlusIconsTable.value).length !== 0) { VRCPlusIconsTable.value.unshift(args.json); @@ -777,8 +779,9 @@ function onFileChangeEmoji(e) { const clearFile = function () { - if (document.querySelector('#EmojiUploadButton')) { - document.querySelector('#EmojiUploadButton').value = ''; + const fileInput = /** @type {HTMLInputElement} */ (document.querySelector('#EmojiUploadButton')); + if (fileInput) { + fileInput.value = ''; } }; const files = e.target.files || e.dataTransfer.files; @@ -818,10 +821,10 @@ if (emojiAnimLoopPingPong.value) { params.loopStyle = 'pingpong'; } - const base64Body = btoa(r.result); + const base64Body = btoa(r.result.toString()); vrcPlusImageRequest.uploadEmoji(base64Body, params).then((args) => { - if (Object.keys(emojiTable).length !== 0) { - emojiTable.unshift(args.json); + if (Object.keys(emojiTable.value).length !== 0) { + emojiTable.value.unshift(args.json); } proxy.$message({ message: t('message.emoji.uploaded'), @@ -873,8 +876,9 @@ function onFileChangeSticker(e) { const clearFile = function () { - if (document.querySelector('#StickerUploadButton')) { - document.querySelector('#StickerUploadButton').value = ''; + const fileInput = /** @type {HTMLInputElement} */ (document.querySelector('#StickerUploadButton')); + if (fileInput) { + fileInput.value = ''; } }; const files = e.target.files || e.dataTransfer.files; @@ -904,7 +908,7 @@ tag: 'sticker', maskTag: 'square' }; - const base64Body = btoa(r.result); + const base64Body = btoa(r.result.toString()); vrcPlusImageRequest.uploadSticker(base64Body, params).then((args) => { handleStickerAdd(args); proxy.$message({ @@ -939,8 +943,9 @@ function onFileChangePrint(e) { const clearFile = function () { - if (document.querySelector('#PrintUploadButton')) { - document.querySelector('#PrintUploadButton').value = ''; + const fileInput = /** @type {HTMLInputElement} */ (document.querySelector('#PrintUploadButton')); + if (fileInput) { + fileInput.value = ''; } }; const files = e.target.files || e.dataTransfer.files; @@ -975,7 +980,7 @@ // worldId: '', timestamp }; - const base64Body = btoa(r.result); + const base64Body = btoa(r.result.toString()); const cropWhiteBorder = printCropBorder.value; vrcPlusImageRequest.uploadPrint(base64Body, cropWhiteBorder, params).then((args) => { proxy.$message({ diff --git a/src/components/dialogs/GroupDialog/GallerySelectDialog.vue b/src/components/dialogs/GroupDialog/GallerySelectDialog.vue index 1cc4c558..5ba75041 100644 --- a/src/components/dialogs/GroupDialog/GallerySelectDialog.vue +++ b/src/components/dialogs/GroupDialog/GallerySelectDialog.vue @@ -84,8 +84,9 @@ function onFileChangeGallery(e) { const clearFile = function () { - if (document.querySelector('#GalleryUploadButton')) { - document.querySelector('#GalleryUploadButton').value = ''; + const fileInput = /** @type{HTMLInputElement} */ (document.querySelector('#GalleryUploadButton')); + if (fileInput) { + fileInput.value = ''; } }; const files = e.target.files || e.dataTransfer.files; @@ -111,7 +112,7 @@ } const r = new FileReader(); r.onload = function () { - const base64Body = btoa(r.result); + const base64Body = btoa(r.result.toString()); vrcPlusImageRequest.uploadGalleryImage(base64Body).then((args) => { handleGalleryImageAdd(args); $message({ diff --git a/src/components/dialogs/VRCXUpdateDialog.vue b/src/components/dialogs/VRCXUpdateDialog.vue index 1aba1838..39bf3271 100644 --- a/src/components/dialogs/VRCXUpdateDialog.vue +++ b/src/components/dialogs/VRCXUpdateDialog.vue @@ -90,7 +90,7 @@ watch( () => VRCXUpdateDialog, (newVal) => { - if (newVal.visible) { + if (newVal.value.visible) { nextTick(() => { adjustDialogZ(VRCXUpdateDialogRef.value.$el); }); diff --git a/src/types/favorite.d.ts b/src/types/favorite.d.ts index 63217188..96d88294 100644 --- a/src/types/favorite.d.ts +++ b/src/types/favorite.d.ts @@ -3,15 +3,6 @@ export type getFavorites = (params: { n: number; offset: number }) => Promise<{ params: { n: number; offset: number }; }>; -interface getFavoritesResponseItem { - favoriteId: string; - id: string; - tags: string[]; - type: 'world' | 'friend' | 'avatar'; -} - -type getFavoritesResponseList = getFavoritesResponseItem[] | undefined; - export type getFavoriteAvatars = (params: { n: number; offset: number; @@ -21,6 +12,36 @@ export type getFavoriteAvatars = (params: { params: { n: number; offset: number; tag: string }; }>; +export type getFavoriteWorlds = (params: { + n: number; + offset: number; +}) => Promise<{ + json: getFavoriteWorldsResponseList; + params: { n: number; offset: number }; +}>; + +export type addFavorite = (params: { + type: string; + favoriteId: string; + tags: string; +}) => Promise<{ + json: addFavoriteResponse; + params: { + type: string; + favoriteId: string; + tags: string; + }; +}>; + +interface getFavoritesResponseItem { + favoriteId: string; + id: string; + tags: string[]; + type: string; +} + +type getFavoritesResponseList = getFavoritesResponseItem[] | undefined; + interface UnityPackage { assetVersion: number; created_at: string; @@ -46,7 +67,7 @@ interface Styles { secondary: null; } -interface AvatarFavoriteItem { +interface getFavoriteAvatarsResponseItem { acknowledgements?: null | string; authorId: string; authorName: string; @@ -73,14 +94,6 @@ interface AvatarFavoriteItem { type getFavoriteAvatarsResponseList = getFavoriteAvatarsResponseItem[]; -export type getFavoriteWorlds = (params: { - n: number; - offset: number; -}) => Promise<{ - json: getFavoriteWorldsResponseList; - params: { n: number; offset: number }; -}>; - interface getFavoriteWorldsResponseItem { id: string; name: string; @@ -109,3 +122,10 @@ interface getFavoriteWorldsResponseItem { } type getFavoriteWorldsResponseList = getFavoriteWorldsResponseItem[]; + +interface addFavoriteResponse { + favoriteId: string; + id: string; + type: 'world' | 'friend' | 'avatar'; + tags: string[]; +} diff --git a/src/types/globals.d.ts b/src/types/globals.d.ts index eaab56b1..c5ad0bef 100644 --- a/src/types/globals.d.ts +++ b/src/types/globals.d.ts @@ -79,37 +79,6 @@ declare global { }; } - declare const API: { - // HTTP request methods - $bulk: (options: any, args?: any) => Promise; - bulk: (options: any) => Promise; - - // Event system - $emit: (event: string, ...args: any[]) => void; - $off: (event: string, handler?: Function) => void; - $on: (event: string, handler: Function) => void; - - // Debug functions - debug: boolean | ((message: any) => void); - debugCurrentUserDiff: boolean | ((data: any) => void); - debugFriendState: boolean | ((data: any) => void); - debugGameLog: boolean | ((data: any) => void); - debugPhotonLogging: boolean | ((data: any) => void); - debugUserDiff: boolean | ((data: any) => void); - debugWebRequests: boolean | ((data: any) => void); - debugWebSocket: boolean | ((data: any) => void); - - // Configuration - dontLogMeOut: boolean; - endpointDomain: string; - endpointDomainVrchat: string; - websocketDomain: string; - websocketDomainVrchat: string; - - // Error handling - errorNoty: (error: any) => void; - }; - const CefSharp: { PostMessage: (message: any) => void; BindObjectAsync: (...args: string[]) => Promise; @@ -419,11 +388,37 @@ declare global { setCookies(cookie: string): Promise; execute(options: { url: string; - method: string; + method?: string; + uploadFilePUT?: boolean; + fileData?: string; + fileMIME?: string; headers?: Record; data?: any; }): Promise<{ status: number; data: string }>; }; + + const electron: { + openFileDialog: () => Promise; + openDirectoryDialog: () => Promise; + desktopNotification: ( + displayName: string, + body?: string, + image?: string + ) => Promise; + onWindowPositionChanged: ( + Function: (event: any, position: { x: number; y: number }) => void + ) => void; + onWindowSizeChanged: ( + Function: ( + event: any, + size: { width: number; height: number } + ) => void + ) => void; + onWindowStateChange: ( + Function: (event: any, state: { windowState: any }) => void + ) => void; + restartApp: () => Promise; + }; } export {}; diff --git a/src/types/group.d.ts b/src/types/group.d.ts index 31eac231..e41f9d82 100644 --- a/src/types/group.d.ts +++ b/src/types/group.d.ts @@ -1,9 +1,9 @@ export type getGroup = (params: { groupId: string; - includeRoles: boolean; + includeRoles?: boolean; }) => Promise<{ json: getGroupResponse; - params: { groupId: string; includeRoles: boolean }; + params: { groupId: string; includeRoles?: boolean }; }>; interface Group { diff --git a/src/types/instance.d.ts b/src/types/instance.d.ts index 4e6cea80..6b7257c9 100644 --- a/src/types/instance.d.ts +++ b/src/types/instance.d.ts @@ -6,6 +6,16 @@ export type getInstance = (params: { params: { worldId: string; instanceId: string }; }>; +export type getInstanceShortName = (instance: { + worldId: string; + instanceId: string; + shortName?: string; +}) => Promise<{ + json: getInstanceShortNameResponse; + instance: { worldId: string; instanceId: string }; + params?: { shortName: string }; +}>; + interface getInstanceResponse { active: boolean; ageGate: boolean; @@ -91,3 +101,8 @@ interface WorldUnityPackage { unityVersion: string; worldSignature: string; } + +interface getInstanceShortNameResponse { + secureName: string; + shortName: string; +} diff --git a/src/types/world.d.ts b/src/types/world.d.ts new file mode 100644 index 00000000..abbe2f09 --- /dev/null +++ b/src/types/world.d.ts @@ -0,0 +1,51 @@ +export type getWorld = (params: { worldId: string }) => Promise<{ + json: getWorldResponse; + params: { worldId: string }; +}>; + +interface getWorldResponse { + authorId: string; + authorName: string; + capacity: number; + created_at: string; + defaultContentSettings: Record; + description: string; + favorites: number; + featured: boolean; + heat: number; + id: string; + imageUrl: string; + instances: any[]; + labsPublicationDate: string; + name: string; + occupants: number; + organization: string; + popularity: number; + previewYoutubeId: string | null; + privateOccupants: number; + publicOccupants: number; + publicationDate: string; + recommendedCapacity: number; + releaseStatus: string; + tags: string[]; + thumbnailImageUrl: string; + udonProducts: any[]; + unityPackages: UnityPackage[]; + updated_at: string; + urlList: any[]; + version: number; + visits: number; +} + +interface UnityPackage { + assetUrl: string; + assetUrlObject: Record; + assetVersion: number; + created_at: string; + id: string; + platform: string; + pluginUrl: string; + pluginUrlObject: Record; + unitySortNumber: number; + unityVersion: string; +}