diff --git a/html/src/app.js b/html/src/app.js index ced32fe1..f9b42142 100644 --- a/html/src/app.js +++ b/html/src/app.js @@ -7825,6 +7825,32 @@ speechSynthesis.getVoices(); } }; + // #endregion + // #region | App: Avatar Memos + + $app.methods.getAvatarMemo = async function (avatarId) { + try { + return await database.getAvatarMemoDB(avatarId); + } catch (err) {console.error(err);} + return { + avatarId: '', + editedAt: '', + memo: '' + }; + }; + + $app.methods.saveAvatarMemo = function (avatarId, memo) { + if (memo) { + database.setAvatarMemo({ + avatarId, + editedAt: new Date().toJSON(), + memo + }); + } else { + database.deleteAvatarMemo(avatarId); + } + }; + // #endregion // #region | App: Friends @@ -17841,6 +17867,7 @@ speechSynthesis.getVoices(); visible: false, loading: false, id: '', + memo: '', ref: {}, isFavorite: false, isBlocked: false, @@ -17854,6 +17881,20 @@ speechSynthesis.getVoices(); fileAnalysis: {} }; + $app.data.ignoreAvatarMemoSave = false; + + $app.watch['avatarDialog.memo'] = function (value) { + if (this.ignoreAvatarMemoSave) { + this.ignoreAvatarMemoSave = false; + return; + } + var D = this.avatarDialog; + if (D.visible === false) { + return; + } + this.saveAvatarMemo(D.id, value == null ? D.memo : value); + }; + API.$on('LOGOUT', function () { $app.avatarDialog.visible = false; }); @@ -17891,6 +17932,8 @@ speechSynthesis.getVoices(); D.isQuestFallback = false; D.isFavorite = API.cachedFavoritesByObjectId.has(avatarId); D.isBlocked = API.cachedAvatarModerations.has(avatarId); + this.ignoreAvatarMemoSave = true; + D.memo = ''; var ref2 = API.cachedAvatars.get(avatarId); if (typeof ref2 !== 'undefined') { D.ref = ref2; @@ -17966,6 +18009,12 @@ speechSynthesis.getVoices(); .finally(() => { D.loading = false; }); + this.getAvatarMemo(avatarId).then((memo) => { + if (D.id === memo.avatarId) { + this.ignoreAvatarMemoSave = true; + D.memo = memo.memo; + } + }); }; $app.methods.avatarDialogCommand = function (command) { diff --git a/html/src/index.pug b/html/src/index.pug index fcb159cf..7dd42017 100644 --- a/html/src/index.pug +++ b/html/src/index.pug @@ -790,6 +790,10 @@ html el-tabs el-tab-pane(:label="$t('dialog.avatar.info.header')") .x-friend-list + .x-friend-item(style="width:100%;cursor:default") + .detail + span.name {{ $t('dialog.avatar.info.memo') }} + el-input.extra(v-model="avatarDialog.memo" size="mini" type="textarea" :rows="2" :autosize="{minRows: 1, maxRows: 20}" :placeholder="$t('dialog.avatar.info.memo_placeholder')" resize="none") .x-friend-item(style="width:100%;cursor:default") .detail span.name {{ $t('dialog.avatar.info.id') }} diff --git a/html/src/localization/strings/en.json b/html/src/localization/strings/en.json index 062dcf65..0592426a 100644 --- a/html/src/localization/strings/en.json +++ b/html/src/localization/strings/en.json @@ -735,7 +735,9 @@ "created_at": "Created At", "last_updated": "Last Updated", "version": "Version", - "platform": "Platform" + "platform": "Platform", + "memo": "Memo", + "memo_placeholder": "Click to add a memo" }, "json": { "header": "JSON", diff --git a/html/src/localization/strings/fr.json b/html/src/localization/strings/fr.json index 64897d3d..2a85d531 100644 --- a/html/src/localization/strings/fr.json +++ b/html/src/localization/strings/fr.json @@ -713,7 +713,9 @@ "created_at": "Créé le", "last_updated": "Dernière mise à jour", "version": "Version", - "platform": "Plateforme" + "platform": "Plateforme", + "memo": "Mémo", + "memo_placeholder": "Cliquez pour ajouter un mémo" }, "json": { "header": "JSON", diff --git a/html/src/localization/strings/ja.json b/html/src/localization/strings/ja.json index a69978d4..15bad562 100644 --- a/html/src/localization/strings/ja.json +++ b/html/src/localization/strings/ja.json @@ -735,7 +735,9 @@ "created_at": "作成日時", "last_updated": "最終更新日時", "version": "バージョン", - "platform": "プラットフォーム" + "platform": "プラットフォーム", + "memo":"メモ (VRCX)", + "memo_placeholder": "クリックしてメモを追加" }, "json": { "header": "JSON", diff --git a/html/src/localization/strings/ko.json b/html/src/localization/strings/ko.json index 752e9f9c..8a068080 100644 --- a/html/src/localization/strings/ko.json +++ b/html/src/localization/strings/ko.json @@ -724,7 +724,9 @@ "created_at": "최초 업로드", "last_updated": "마지막 업데이트", "version": "버전", - "platform": "플랫폼" + "platform": "플랫폼", + "memo": "VRCX 메모", + "memo_placeholder": "-" }, "json": { "header": "JSON", diff --git a/html/src/localization/strings/zh_CN.json b/html/src/localization/strings/zh_CN.json index 113055f1..2499459b 100644 --- a/html/src/localization/strings/zh_CN.json +++ b/html/src/localization/strings/zh_CN.json @@ -707,7 +707,9 @@ "created_at": "创建时间", "last_updated": "最后更新", "version": "版本", - "platform": "平台" + "platform": "平台", + "memo":"VRCX 本地备忘信息", + "memo_placeholder": "点击添加备忘录" }, "json": { "header": "原始JSON信息", diff --git a/html/src/localization/strings/zh_TW.json b/html/src/localization/strings/zh_TW.json index 55d5cf19..e009f54c 100644 --- a/html/src/localization/strings/zh_TW.json +++ b/html/src/localization/strings/zh_TW.json @@ -701,7 +701,9 @@ "created_at": "創建時間", "last_updated": "最後更新", "version": "版本", - "platform": "平台" + "platform": "平台", + "memo": "備忘錄", + "memo_placeholder": "點擊新增備忘錄" }, "json": { "header": "原始資料", diff --git a/html/src/repository/database.js b/html/src/repository/database.js index 5f13f780..b76606de 100644 --- a/html/src/repository/database.js +++ b/html/src/repository/database.js @@ -44,6 +44,9 @@ class Database { await sqliteService.executeNonQuery( `CREATE TABLE IF NOT EXISTS world_memos (world_id TEXT PRIMARY KEY, edited_at TEXT, memo TEXT)` ); + await sqliteService.executeNonQuery( + `CREATE TABLE IF NOT EXISTS avatar_memos (avatar_id TEXT PRIMARY KEY, edited_at TEXT, memo TEXT)` + ); } async initTables() { @@ -270,6 +273,46 @@ class Database { ); } + // Avatar memos + + async getAvatarMemoDB(avatarId) { + var row = {}; + await sqliteService.execute( + (dbRow) => { + row = { + avatarId: dbRow[0], + editedAt: dbRow[1], + memo: dbRow[2] + }; + }, + `SELECT * FROM avatar_memos WHERE avatar_id = @avatar_id`, + { + '@avatar_id': avatarId + } + ); + return row; + } + + setAvatarMemo(entry) { + sqliteService.executeNonQuery( + `INSERT OR REPLACE INTO avatar_memos (avatar_id, edited_at, memo) VALUES (@avatar_id, @edited_at, @memo)`, + { + '@avatar_id': entry.avatarId, + '@edited_at': entry.editedAt, + '@memo': entry.memo + } + ); + } + + deleteAvatarMemo(avatarId) { + sqliteService.executeNonQuery( + `DELETE FROM avatar_memos WHERE avatar_id = @avatar_id`, + { + '@avatar_id': avatarId + } + ); + } + async getFriendLogCurrent() { var friendLogCurrent = []; await sqliteService.execute((dbRow) => {