diff --git a/html/src/app.js b/html/src/app.js
index 858aaa01..65522e23 100644
--- a/html/src/app.js
+++ b/html/src/app.js
@@ -7721,6 +7721,9 @@ speechSynthesis.getVoices();
}
};
+ // #endregion
+ // #region | User Memos
+
$app.methods.migrateMemos = async function () {
var json = JSON.parse(await VRCXStorage.GetAll());
database.begin();
@@ -7785,6 +7788,32 @@ speechSynthesis.getVoices();
});
};
+ // #endregion
+ // #region | World Memos
+
+ $app.methods.getWorldMemo = async function (worldId) {
+ try {
+ return await database.getWorldMemo(worldId);
+ } catch (err) {}
+ return {
+ worldId: '',
+ editedAt: '',
+ memo: ''
+ };
+ };
+
+ $app.methods.saveWorldMemo = function (worldId, memo) {
+ if (memo) {
+ database.setWorldMemo({
+ worldId,
+ editedAt: new Date().toJSON(),
+ memo
+ });
+ } else {
+ database.deleteWorldMemo(worldId);
+ }
+ };
+
// #endregion
// #region | App: Friends
@@ -16942,6 +16971,7 @@ speechSynthesis.getVoices();
visible: false,
loading: false,
id: '',
+ memo: '',
$location: {},
ref: {},
isFavorite: false,
@@ -16961,6 +16991,17 @@ speechSynthesis.getVoices();
isIos: false
};
+ $app.data.ignoreWorldMemoSave = false;
+
+ $app.watch['worldDialog.memo'] = function () {
+ if (this.ignoreWorldMemoSave) {
+ this.ignoreWorldMemoSave = false;
+ return;
+ }
+ var D = this.worldDialog;
+ this.saveWorldMemo(D.id, D.memo);
+ };
+
API.$on('LOGOUT', function () {
$app.worldDialog.visible = false;
});
@@ -17082,11 +17123,19 @@ speechSynthesis.getVoices();
D.isPC = false;
D.isQuest = false;
D.isIos = false;
+ this.ignoreWorldMemoSave = true;
+ D.memo = '';
var LL = API.parseLocation(this.lastLocation.location);
var currentWorldMatch = false;
if (LL.worldId === D.id) {
currentWorldMatch = true;
}
+ this.getWorldMemo(D.id).then((memo) => {
+ if (memo.worldId === D.id) {
+ this.ignoreWorldMemoSave = true;
+ D.memo = memo.memo;
+ }
+ });
database.getLastVisit(D.id, currentWorldMatch).then((ref) => {
if (ref.worldId === D.id) {
D.lastVisit = ref.created_at;
diff --git a/html/src/index.pug b/html/src/index.pug
index 47934f95..8a2aa2df 100644
--- a/html/src/index.pug
+++ b/html/src/index.pug
@@ -641,6 +641,10 @@ html
timer(:epoch="user.$location_at")
el-tab-pane(:label="$t('dialog.world.info.header')")
.x-friend-list(style="max-height:none")
+ .x-friend-item(style="width:100%;cursor:default")
+ .detail
+ span.name {{ $t('dialog.world.info.memo') }}
+ el-input.extra(v-model="worldDialog.memo" type="textarea" :rows="2" :autosize="{ minRows: 1, maxRows: 20 }" :placeholder="$t('dialog.world.info.memo_placeholder')" size="mini" resize="none")
div(style="width:100%;display:flex")
.x-friend-item(style="width:350px;cursor:default")
.detail
diff --git a/html/src/localization/strings/en.json b/html/src/localization/strings/en.json
index 6fff5556..7d10dd6c 100644
--- a/html/src/localization/strings/en.json
+++ b/html/src/localization/strings/en.json
@@ -644,6 +644,8 @@
},
"info": {
"header": "Info",
+ "memo": "Memo",
+ "memo_placeholder": "Click to add a memo",
"id": "World ID",
"id_tooltip": "Copy to clipboard",
"copy_id": "Copy ID",
diff --git a/html/src/repository/database.js b/html/src/repository/database.js
index 7458cd81..0ee0887e 100644
--- a/html/src/repository/database.js
+++ b/html/src/repository/database.js
@@ -41,6 +41,9 @@ class Database {
await sqliteService.executeNonQuery(
`CREATE TABLE IF NOT EXISTS memos (user_id TEXT PRIMARY KEY, edited_at TEXT, memo TEXT)`
);
+ await sqliteService.executeNonQuery(
+ `CREATE TABLE IF NOT EXISTS world_memos (world_id TEXT PRIMARY KEY, edited_at TEXT, memo TEXT)`
+ );
}
async initTables() {
@@ -172,6 +175,8 @@ class Database {
sqliteService.executeNonQuery('COMMIT');
}
+ // memos
+
async getMemo(userId) {
var row = {};
await sqliteService.execute(
@@ -222,6 +227,46 @@ class Database {
);
}
+ // world memos
+
+ async getWorldMemo(worldId) {
+ var row = {};
+ await sqliteService.execute(
+ (dbRow) => {
+ row = {
+ worldId: dbRow[0],
+ editedAt: dbRow[1],
+ memo: dbRow[2]
+ };
+ },
+ `SELECT * FROM world_memos WHERE world_id = @world_id`,
+ {
+ '@world_id': worldId
+ }
+ );
+ return row;
+ }
+
+ setWorldMemo(entry) {
+ sqliteService.executeNonQuery(
+ `INSERT OR REPLACE INTO world_memos (world_id, edited_at, memo) VALUES (@world_id, @edited_at, @memo)`,
+ {
+ '@world_id': entry.worldId,
+ '@edited_at': entry.editedAt,
+ '@memo': entry.memo
+ }
+ );
+ }
+
+ deleteWorldMemo(worldId) {
+ sqliteService.executeNonQuery(
+ `DELETE FROM world_memos WHERE world_id = @world_id`,
+ {
+ '@world_id': worldId
+ }
+ );
+ }
+
async getFriendLogCurrent() {
var friendLogCurrent = [];
await sqliteService.execute((dbRow) => {