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) => {