Move feed logs to SQLite

This commit is contained in:
Natsumi
2021-07-01 01:02:17 +12:00
parent a18a9ab53a
commit 2af8ba89c0
5 changed files with 400 additions and 186 deletions

View File

@@ -22,6 +22,7 @@ import configRepository from './repository/config.js';
import webApiService from './service/webapi.js'; import webApiService from './service/webapi.js';
import gameLogService from './service/gamelog.js'; import gameLogService from './service/gamelog.js';
import security from './security.js'; import security from './security.js';
import database from './repository/database.js';
speechSynthesis.getVoices(); speechSynthesis.getVoices();
@@ -40,6 +41,7 @@ speechSynthesis.getVoices();
); );
await configRepository.init(); await configRepository.init();
await database.init();
if (configRepository.getBool('migrate_config_20201101') === null) { if (configRepository.getBool('migrate_config_20201101') === null) {
var legacyConfigKeys = [ var legacyConfigKeys = [
@@ -849,7 +851,9 @@ speechSynthesis.getVoices();
template: '<div @click="confirm" style="cursor:pointer;width:fit-content;display:inline-block;vertical-align:top"><span style="display:inline-block;margin-right:5px">{{ avatarName }}</span><span :class="color">{{ avatarType }}</span></div>', template: '<div @click="confirm" style="cursor:pointer;width:fit-content;display:inline-block;vertical-align:top"><span style="display:inline-block;margin-right:5px">{{ avatarName }}</span><span :class="color">{{ avatarType }}</span></div>',
props: { props: {
imageurl: String, imageurl: String,
userid: String userid: String,
hintownerid: String,
hintavatarname: String
}, },
data() { data() {
return { return {
@@ -860,15 +864,25 @@ speechSynthesis.getVoices();
}, },
methods: { methods: {
async parse() { async parse() {
this.ownerId = '';
this.avatarName = ''; this.avatarName = '';
this.avatarType = ''; this.avatarType = '';
this.color = ''; this.color = '';
var avatarInfo = await $app.getAvatarName(this.imageurl); if (this.hintownerid) {
this.avatarName = avatarInfo.avatarName; this.avatarName = this.hintavatarname;
if ((typeof this.userid === 'undefined') || (!avatarInfo.ownerId)) { this.ownerId = this.hintownerid;
} else {
try {
var avatarInfo = await $app.getAvatarName(this.imageurl);
this.avatarName = avatarInfo.avatarName;
this.ownerId = avatarInfo.ownerId;
} catch (err) {
}
}
if ((typeof this.userid === 'undefined') || (!this.ownerId)) {
this.color = 'avatar-info-unknown'; this.color = 'avatar-info-unknown';
this.avatarType = '(unknown)'; this.avatarType = '(unknown)';
} else if (avatarInfo.ownerId === this.userid) { } else if (this.ownerId === this.userid) {
this.color = 'avatar-info-own'; this.color = 'avatar-info-own';
this.avatarType = '(own)'; this.avatarType = '(own)';
} else { } else {
@@ -3953,14 +3967,14 @@ speechSynthesis.getVoices();
if (ctx.created_at < bias) { if (ctx.created_at < bias) {
break; break;
} }
if ((ctx.type === 'GPS') && (ctx.location[0] === this.lastLocation.location)) { if ((ctx.type === 'GPS') && (ctx.location === this.lastLocation.location)) {
if (joiningMap[ctx.displayName]) { if (joiningMap[ctx.displayName]) {
continue; continue;
} }
joiningMap[ctx.displayName] = ctx.created_at; joiningMap[ctx.displayName] = ctx.created_at;
if (API.cachedUsers.has(ctx.userId)) { if (API.cachedUsers.has(ctx.userId)) {
var user = API.cachedUsers.get(ctx.userId); var user = API.cachedUsers.get(ctx.userId);
if (ctx.location[0] !== user.location) { if (ctx.location !== user.location) {
continue; continue;
} }
} }
@@ -4285,7 +4299,7 @@ speechSynthesis.getVoices();
} }
// hide private worlds from feeds // hide private worlds from feeds
if ((this.hidePrivateFromFeed) && if ((this.hidePrivateFromFeed) &&
(ctx.type === 'GPS') && (ctx.location[0] === 'private')) { (ctx.type === 'GPS') && (ctx.location === 'private')) {
continue; continue;
} }
var isFriend = this.friends.has(ctx.userId); var isFriend = this.friends.has(ctx.userId);
@@ -4575,7 +4589,7 @@ speechSynthesis.getVoices();
} }
}; };
$app.methods.playNotyTTS = async function (noty, message) { $app.methods.playNotyTTS = function (noty, message) {
switch (noty.type) { switch (noty.type) {
case 'OnPlayerJoined': case 'OnPlayerJoined':
this.speak(`${noty.data} has joined`); this.speak(`${noty.data} has joined`);
@@ -4587,7 +4601,7 @@ speechSynthesis.getVoices();
this.speak(`${noty.displayName} is joining`); this.speak(`${noty.displayName} is joining`);
break; break;
case 'GPS': case 'GPS':
this.speak(`${noty.displayName} is in ${await this.displayLocation(noty.location[0])}`); this.speak(`${noty.displayName} is in ${this.displayLocation(noty.location, noty.worldName)}`);
break; break;
case 'Online': case 'Online':
this.speak(`${noty.displayName} has logged in`); this.speak(`${noty.displayName} has logged in`);
@@ -4596,7 +4610,7 @@ speechSynthesis.getVoices();
this.speak(`${noty.displayName} has logged out`); this.speak(`${noty.displayName} has logged out`);
break; break;
case 'Status': case 'Status':
this.speak(`${noty.displayName} status is now ${noty.status[0].status} ${noty.status[0].statusDescription}`); this.speak(`${noty.displayName} status is now ${noty.status} ${noty.statusDescription}`);
break; break;
case 'invite': case 'invite':
this.speak(`${noty.senderUsername} has invited you to ${noty.details.worldName}${message}`); this.speak(`${noty.senderUsername} has invited you to ${noty.details.worldName}${message}`);
@@ -4651,7 +4665,7 @@ speechSynthesis.getVoices();
} }
}; };
$app.methods.displayXSNotification = async function (noty, message, image) { $app.methods.displayXSNotification = function (noty, message, image) {
var timeout = parseInt(parseInt(this.notificationTimeout) / 1000); var timeout = parseInt(parseInt(this.notificationTimeout) / 1000);
switch (noty.type) { switch (noty.type) {
case 'OnPlayerJoined': case 'OnPlayerJoined':
@@ -4664,7 +4678,7 @@ speechSynthesis.getVoices();
AppApi.XSNotification('VRCX', `${noty.displayName} is joining`, timeout, image); AppApi.XSNotification('VRCX', `${noty.displayName} is joining`, timeout, image);
break; break;
case 'GPS': case 'GPS':
AppApi.XSNotification('VRCX', `${noty.displayName} is in ${await this.displayLocation(noty.location[0])}`, timeout, image); AppApi.XSNotification('VRCX', `${noty.displayName} is in ${this.displayLocation(noty.location, noty.worldName)}`, timeout, image);
break; break;
case 'Online': case 'Online':
AppApi.XSNotification('VRCX', `${noty.displayName} has logged in`, timeout, image); AppApi.XSNotification('VRCX', `${noty.displayName} has logged in`, timeout, image);
@@ -4673,7 +4687,7 @@ speechSynthesis.getVoices();
AppApi.XSNotification('VRCX', `${noty.displayName} has logged out`, timeout, image); AppApi.XSNotification('VRCX', `${noty.displayName} has logged out`, timeout, image);
break; break;
case 'Status': case 'Status':
AppApi.XSNotification('VRCX', `${noty.displayName} status is now ${noty.status[0].status} ${noty.status[0].statusDescription}`, timeout, image); AppApi.XSNotification('VRCX', `${noty.displayName} status is now ${noty.status} ${noty.statusDescription}`, timeout, image);
break; break;
case 'invite': case 'invite':
AppApi.XSNotification('VRCX', `${noty.senderUsername} has invited you to ${noty.details.worldName}${message}`, timeout, image); AppApi.XSNotification('VRCX', `${noty.senderUsername} has invited you to ${noty.details.worldName}${message}`, timeout, image);
@@ -4728,7 +4742,7 @@ speechSynthesis.getVoices();
} }
}; };
$app.methods.displayDesktopToast = async function (noty, message, image) { $app.methods.displayDesktopToast = function (noty, message, image) {
switch (noty.type) { switch (noty.type) {
case 'OnPlayerJoined': case 'OnPlayerJoined':
AppApi.DesktopNotification(noty.data, 'has joined', image); AppApi.DesktopNotification(noty.data, 'has joined', image);
@@ -4740,7 +4754,7 @@ speechSynthesis.getVoices();
AppApi.DesktopNotification(noty.displayName, 'is joining', image); AppApi.DesktopNotification(noty.displayName, 'is joining', image);
break; break;
case 'GPS': case 'GPS':
AppApi.DesktopNotification(noty.displayName, `is in ${await this.displayLocation(noty.location[0])}`, image); AppApi.DesktopNotification(noty.displayName, `is in ${this.displayLocation(noty.location, noty.worldName)}`, image);
break; break;
case 'Online': case 'Online':
AppApi.DesktopNotification(noty.displayName, 'has logged in', image); AppApi.DesktopNotification(noty.displayName, 'has logged in', image);
@@ -4749,7 +4763,7 @@ speechSynthesis.getVoices();
AppApi.DesktopNotification(noty.displayName, 'has logged out', image); AppApi.DesktopNotification(noty.displayName, 'has logged out', image);
break; break;
case 'Status': case 'Status':
AppApi.DesktopNotification(noty.displayName, `status is now ${noty.status[0].status} ${noty.status[0].statusDescription}`, image); AppApi.DesktopNotification(noty.displayName, `status is now ${noty.status} ${noty.statusDescription}`, image);
break; break;
case 'invite': case 'invite':
AppApi.DesktopNotification(noty.senderUsername, `has invited you to ${noty.details.worldName}${message}`, image); AppApi.DesktopNotification(noty.senderUsername, `has invited you to ${noty.details.worldName}${message}`, image);
@@ -4804,7 +4818,7 @@ speechSynthesis.getVoices();
} }
}; };
$app.methods.displayLocation = async function (location) { $app.methods.displayLocation = function (location, worldName) {
var text = ''; var text = '';
var L = API.parseLocation(location); var L = API.parseLocation(location);
if (L.isOffline) { if (L.isOffline) {
@@ -4812,23 +4826,10 @@ speechSynthesis.getVoices();
} else if (L.isPrivate) { } else if (L.isPrivate) {
text = 'Private'; text = 'Private';
} else if (L.worldId) { } else if (L.worldId) {
var ref = API.cachedWorlds.get(L.worldId); if (L.instanceId) {
if (typeof ref === 'undefined') { text = `${worldName} ${L.accessType}`;
await API.getWorld({
worldId: L.worldId
}).then((args) => {
if (L.tag === location) {
if (L.instanceId) {
text = `${args.json.name} ${L.accessType}`;
} else {
text = args.json.name;
}
}
});
} else if (L.instanceId) {
text = `${ref.name} ${L.accessType}`;
} else { } else {
text = ref.name; text = worldName;
} }
} }
return text; return text;
@@ -5660,8 +5661,22 @@ speechSynthesis.getVoices();
if (ctx.state === 'online') { if (ctx.state === 'online') {
var ts = Date.now(); var ts = Date.now();
var time = ts - $location_at; var time = ts - $location_at;
if (location === 'offline') {
location = '';
}
var worldName = await this.getWorldName(location);
this.addFeed('Offline', ctx.ref, { this.addFeed('Offline', ctx.ref, {
location: (location === 'offline') ? '' : location, location,
worldName,
time
});
database.addOnlineOfflineToDatabase({
created_at: new Date().toJSON(),
userId: ctx.ref.id,
displayName: ctx.ref.displayName,
type: 'Offline',
location,
worldName,
time time
}); });
} }
@@ -5669,8 +5684,19 @@ speechSynthesis.getVoices();
ctx.ref.$location_at = Date.now(); ctx.ref.$location_at = Date.now();
ctx.ref.$online_for = Date.now(); ctx.ref.$online_for = Date.now();
ctx.ref.$offline_for = ''; ctx.ref.$offline_for = '';
var worldName = await this.getWorldName(ctx.ref.location);
this.addFeed('Online', ctx.ref, { this.addFeed('Online', ctx.ref, {
location: ctx.ref.location location: ctx.ref.location,
worldName
});
database.addOnlineOfflineToDatabase({
created_at: new Date().toJSON(),
userId: ctx.ref.id,
displayName: ctx.ref.displayName,
type: 'Online',
location,
worldName,
time: ''
}); });
} }
} }
@@ -5723,6 +5749,21 @@ speechSynthesis.getVoices();
this.updateFriendInProgress.delete(id); this.updateFriendInProgress.delete(id);
}; };
$app.methods.getWorldName = async function (location) {
var worldName = '';
try {
var L = API.parseLocation(location);
if (L.worldId) {
var args = await API.getCachedWorld({
worldId: L.worldId
});
worldName = args.ref.name;
}
} catch (err) {
}
return worldName;
};
$app.methods.updateFriendGPS = function (userId) { $app.methods.updateFriendGPS = function (userId) {
if (!this.orderFriendsGroupGPS) { if (!this.orderFriendsGroupGPS) {
return; return;
@@ -5911,6 +5952,26 @@ speechSynthesis.getVoices();
return style; return style;
}; };
$app.methods.statusClass = function (status) {
var style = {};
if (typeof status !== 'undefined') {
if (status === 'active') {
// Online
style.online = true;
} else if (status === 'join me') {
// Join Me
style.joinme = true;
} else if (status === 'ask me') {
// Ask Me
style.askme = true;
} else if (status === 'busy') {
// Do Not Disturb
style.busy = true;
}
}
return style;
};
$app.methods.confirmDeleteFriend = function (id) { $app.methods.confirmDeleteFriend = function (id) {
this.$confirm('Continue? Unfriend', 'Confirm', { this.$confirm('Continue? Unfriend', 'Confirm', {
confirmButtonText: 'Confirm', confirmButtonText: 'Confirm',
@@ -6056,12 +6117,13 @@ speechSynthesis.getVoices();
$app.data.feedTable.filters[0].value = JSON.parse(configRepository.getString('VRCX_feedTableFilters')); $app.data.feedTable.filters[0].value = JSON.parse(configRepository.getString('VRCX_feedTableFilters'));
} }
API.$on('LOGIN', function (args) { API.$on('LOGIN', async function (args) {
$app.feedTable.data = VRCXStorage.GetArray(`${args.ref.id}_feedTable`); $app.feedTable.data = await database.getFeedDatabase();
$app.sweepFeed(); //$app.feedTable.data = VRCXStorage.GetArray(`${args.ref.id}_feedTable`);
//$app.sweepFeed();
}); });
API.$on('USER:UPDATE', function (args) { API.$on('USER:UPDATE', async function (args) {
var { ref, props } = args; var { ref, props } = args;
if ($app.friends.has(ref.id) === false) { if ($app.friends.has(ref.id) === false) {
return; return;
@@ -6071,60 +6133,99 @@ speechSynthesis.getVoices();
(props.location[0] !== '') && (props.location[0] !== '') &&
(props.location[1] !== 'offline') && (props.location[1] !== 'offline') &&
(props.location[1] !== '')) { (props.location[1] !== '')) {
var worldName = await $app.getWorldName(props.location[0]);
$app.addFeed('GPS', ref, { $app.addFeed('GPS', ref, {
location: [ location: props.location[0],
props.location[0], worldName,
props.location[1] previousLocation: props.location[1],
], time: props.location[2]
});
database.addGPSToDatabase({
created_at: new Date().toJSON(),
userId: ref.id,
displayName: ref.displayName,
location: props.location[0],
worldName,
previousLocation: props.location[1],
time: props.location[2] time: props.location[2]
}); });
$app.updateFriendGPS(ref.id); $app.updateFriendGPS(ref.id);
$app.feedDownloadWorldCache(ref); $app.feedDownloadWorldCache(ref.id, props.location[0]);
} }
if (props.currentAvatarImageUrl || if (props.currentAvatarImageUrl ||
props.currentAvatarThumbnailImageUrl) { props.currentAvatarThumbnailImageUrl) {
if (props.currentAvatarImageUrl) {
var currentAvatarImageUrl = props.currentAvatarImageUrl[0];
var previousCurrentAvatarImageUrl = props.currentAvatarImageUrl[1];
} else {
var currentAvatarImageUrl = ref.currentAvatarImageUrl;
var previousCurrentAvatarImageUrl = ref.currentAvatarImageUrl;
}
if (props.currentAvatarThumbnailImageUrl) {
var currentAvatarThumbnailImageUrl = props.currentAvatarThumbnailImageUrl[0];
var previousCurrentAvatarThumbnailImageUrl = props.currentAvatarThumbnailImageUrl[1];
} else {
var currentAvatarThumbnailImageUrl = ref.currentAvatarThumbnailImageUrl;
var previousCurrentAvatarThumbnailImageUrl = ref.currentAvatarThumbnailImageUrl;
}
var avatarInfo = {
ownerId: '',
avatarName: ''
}
try {
avatarInfo = await $app.getAvatarName(currentAvatarImageUrl);
} catch (err) {
}
$app.addFeed('Avatar', ref, { $app.addFeed('Avatar', ref, {
avatar: [ ownerId: avatarInfo.ownerId,
{ avatarName: avatarInfo.avatarName,
currentAvatarImageUrl: props.currentAvatarImageUrl currentAvatarImageUrl,
? props.currentAvatarImageUrl[0] currentAvatarThumbnailImageUrl,
: ref.currentAvatarImageUrl, previousCurrentAvatarImageUrl,
currentAvatarThumbnailImageUrl: props.currentAvatarThumbnailImageUrl previousCurrentAvatarThumbnailImageUrl
? props.currentAvatarThumbnailImageUrl[0] });
: ref.currentAvatarThumbnailImageUrl database.addAvatarToDatabase({
}, created_at: new Date().toJSON(),
{ userId: ref.id,
currentAvatarImageUrl: props.currentAvatarImageUrl displayName: ref.displayName,
? props.currentAvatarImageUrl[1] ownerId: avatarInfo.ownerId,
: ref.currentAvatarImageUrl, avatarName: avatarInfo.avatarName,
currentAvatarThumbnailImageUrl: props.currentAvatarThumbnailImageUrl currentAvatarImageUrl,
? props.currentAvatarThumbnailImageUrl[1] currentAvatarThumbnailImageUrl,
: ref.currentAvatarThumbnailImageUrl previousCurrentAvatarImageUrl,
} previousCurrentAvatarThumbnailImageUrl
]
}); });
} }
if (props.status || if (props.status ||
props.statusDescription) { props.statusDescription) {
if (props.status) {
var status = props.status[0];
var previousStatus = props.status[1];
} else {
var status = ref.status;
var previousStatus = ref.status;
}
if (props.statusDescription) {
var statusDescription = props.statusDescription[0];
var previousStatusDescription = props.statusDescription[1];
} else {
var statusDescription = ref.statusDescription;
var previousStatusDescription = ref.statusDescription;
}
$app.addFeed('Status', ref, { $app.addFeed('Status', ref, {
status: [ status,
{ statusDescription,
status: props.status previousStatus,
? props.status[0] previousStatusDescription
: ref.status, });
statusDescription: props.statusDescription database.addStatusToDatabase({
? props.statusDescription[0] created_at: new Date().toJSON(),
: ref.statusDescription userId: ref.id,
}, displayName: ref.displayName,
{ status,
status: props.status statusDescription,
? props.status[1] previousStatus,
: ref.status, previousStatusDescription
statusDescription: props.statusDescription
? props.statusDescription[1]
: ref.statusDescription
}
]
}); });
} }
}); });
@@ -6148,8 +6249,8 @@ speechSynthesis.getVoices();
displayName: ref.displayName, displayName: ref.displayName,
...extra ...extra
}); });
this.sweepFeed(); //this.sweepFeed();
this.saveFeed(); //this.saveFeed();
this.updateSharedFeed(false); this.updateSharedFeed(false);
this.notifyMenu('feed'); this.notifyMenu('feed');
}; };
@@ -12539,18 +12640,18 @@ speechSynthesis.getVoices();
} }
}; };
$app.methods.feedDownloadWorldCache = function (feed) { $app.methods.feedDownloadWorldCache = function (id, location) {
if ((this.worldAutoCacheGPS === 'Always') || if ((this.worldAutoCacheGPS === 'Always') ||
((this.worldAutoCacheGPS === 'Game Closed') && (!this.isGameRunning)) || ((this.worldAutoCacheGPS === 'Game Closed') && (!this.isGameRunning)) ||
((this.worldAutoCacheGPS === 'Game Running') && (this.isGameRunning))) { ((this.worldAutoCacheGPS === 'Game Running') && (this.isGameRunning))) {
if ((feed.location === '') || if ((location === '') ||
(feed.location === 'offline') || (location === 'offline') ||
(feed.location === 'private') || (location === 'private') ||
((!this.worldAutoCacheGPSFilter) && ((!this.worldAutoCacheGPSFilter) &&
(!API.cachedFavoritesByObjectId.has(feed.id)))) { (!API.cachedFavoritesByObjectId.has(id)))) {
return; return;
} }
this.autoDownloadWorldCache(feed.location, 'GPS', feed.id); this.autoDownloadWorldCache(location, 'GPS', id);
} }
}; };

View File

@@ -87,61 +87,49 @@ html
template(v-once #default="scope") template(v-once #default="scope")
div(style="position:relative;font-size:14px") div(style="position:relative;font-size:14px")
template(v-if="scope.row.type === 'GPS'") template(v-if="scope.row.type === 'GPS'")
location(v-if="scope.row.location[1]" :location="scope.row.location[1]") location(v-if="scope.row.previousLocation" :location="scope.row.previousLocation")
el-tag(type="info" effect="plain" size="mini" style="margin-left:5px") {{ scope.row.time | timeToText }} el-tag(type="info" effect="plain" size="mini" style="margin-left:5px") {{ scope.row.time | timeToText }}
br br
span span
i.el-icon-right i.el-icon-right
location(v-if="scope.row.location[0]" :location="scope.row.location[0]") location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName")
template(v-else-if="scope.row.type === 'Offline'") template(v-else-if="scope.row.type === 'Offline'")
template(v-if="scope.row.location") template(v-if="scope.row.location")
location(:location="scope.row.location") location(:location="scope.row.location" :hint="scope.row.worldName")
el-tag(type="info" effect="plain" size="mini" style="margin-left:5px") {{ scope.row.time | timeToText }} el-tag(type="info" effect="plain" size="mini" style="margin-left:5px") {{ scope.row.time | timeToText }}
template(v-else-if="scope.row.type === 'Online'") template(v-else-if="scope.row.type === 'Online'")
location(v-if="scope.row.location" :location="scope.row.location") location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName")
template(v-else-if="scope.row.type === 'Avatar'") template(v-else-if="scope.row.type === 'Avatar'")
template(v-if="scope.row.avatar[0] === Object(scope.row.avatar[0])") el-popover(placement="right" width="500px" trigger="click")
//- high resolution (v2) 2020.07.12~ img.x-link(slot="reference" v-lazy="scope.row.previousCurrentAvatarThumbnailImageUrl" style="flex:none;width:160px;height:120px;border-radius:4px")
el-popover(placement="right" width="500px" trigger="click") img.x-link(v-lazy="scope.row.previousCurrentAvatarImageUrl" style="width:500px;height:375px" @click="showAvatarAuthorDialog(scope.row.userId, scope.row.previousCurrentAvatarImageUrl)")
img.x-link(slot="reference" v-lazy="scope.row.avatar[1].currentAvatarThumbnailImageUrl" style="flex:none;width:160px;height:120px;border-radius:4px") span(style="position:relative;top:-50px;margin:0 5px")
img.x-link(v-lazy="scope.row.avatar[1].currentAvatarImageUrl" style="width:500px;height:375px" @click="showAvatarAuthorDialog(scope.row.userId, scope.row.avatar[1].currentAvatarImageUrl)") i.el-icon-right
span(style="position:relative;top:-50px;margin:0 5px") el-popover(placement="right" width="500px" trigger="click")
i.el-icon-right img.x-link(slot="reference" v-lazy="scope.row.currentAvatarThumbnailImageUrl" style="flex:none;width:160px;height:120px;border-radius:4px")
el-popover(placement="right" width="500px" trigger="click") img.x-link(v-lazy="scope.row.currentAvatarImageUrl" style="width:500px;height:375px" @click="showAvatarAuthorDialog(scope.row.userId, scope.row.currentAvatarImageUrl)")
img.x-link(slot="reference" v-lazy="scope.row.avatar[0].currentAvatarThumbnailImageUrl" style="flex:none;width:160px;height:120px;border-radius:4px")
img.x-link(v-lazy="scope.row.avatar[0].currentAvatarImageUrl" style="width:500px;height:375px" @click="showAvatarAuthorDialog(scope.row.userId, scope.row.avatar[0].currentAvatarImageUrl)")
template(v-else)
//- legacy
el-popover(placement="right" width="500px" trigger="click")
img.x-link(slot="reference" v-lazy="scope.row.avatar[1]" style="flex:none;width:160px;height:120px;border-radius:4px")
img.x-link(v-lazy="scope.row.avatar[1]" style="width:500px;height:375px" @click="openExternalLink(scope.row.avatar[1])")
span(style="position:relative;top:-50px;margin:0 5px")
i.el-icon-right
el-popover(placement="right" width="500px" trigger="click")
img.x-link(slot="reference" v-lazy="scope.row.avatar[0]" style="flex:none;width:160px;height:120px;border-radius:4px")
img.x-link(v-lazy="scope.row.avatar[0]" style="width:500px;height:375px" @click="openExternalLink(scope.row.avatar[0])")
template(v-else-if="scope.row.type === 'Status'") template(v-else-if="scope.row.type === 'Status'")
el-tooltip(placement="top") el-tooltip(placement="top")
template(#content) template(#content)
span(v-if="scope.row.status[1].status === 'active'") Active span(v-if="scope.row.previousStatus === 'active'") Active
span(v-else-if="scope.row.status[1].status === 'join me'") Join Me span(v-else-if="scope.row.previousStatus === 'join me'") Join Me
span(v-else-if="scope.row.status[1].status === 'ask me'") Ask Me span(v-else-if="scope.row.previousStatus === 'ask me'") Ask Me
span(v-else-if="scope.row.status[1].status === 'busy'") Do Not Disturb span(v-else-if="scope.row.previousStatus === 'busy'") Do Not Disturb
span(v-else) Offline span(v-else) Offline
i.x-user-status(:class="userStatusClass(scope.row.status[1])") i.x-user-status(:class="statusClass(scope.row.previousStatus)")
span(v-text="scope.row.status[1].statusDescription") span(v-text="scope.row.previousStatusDescription")
br br
span span
i.el-icon-right i.el-icon-right
el-tooltip(placement="top") el-tooltip(placement="top")
template(#content) template(#content)
span(v-if="scope.row.status[0].status === 'active'") Active span(v-if="scope.row.status === 'active'") Active
span(v-else-if="scope.row.status[0].status === 'join me'") Join Me span(v-else-if="scope.row.status === 'join me'") Join Me
span(v-else-if="scope.row.status[0].status === 'ask me'") Ask Me span(v-else-if="scope.row.status === 'ask me'") Ask Me
span(v-else-if="scope.row.status[0].status === 'busy'") Do Not Disturb span(v-else-if="scope.row.status === 'busy'") Do Not Disturb
span(v-else) Offline span(v-else) Offline
i.x-user-status(:class="userStatusClass(scope.row.status[0])") i.x-user-status(:class="statusClass(scope.row.status)")
span(v-text="scope.row.status[0].statusDescription") span(v-text="scope.row.statusDescription")
el-table-column(label="Date" prop="created_at" sortable="custom" width="90") el-table-column(label="Date" prop="created_at" sortable="custom" width="90")
template(v-once #default="scope") template(v-once #default="scope")
el-tooltip(placement="right") el-tooltip(placement="right")
@@ -155,21 +143,21 @@ html
el-table-column(label="Detail") el-table-column(label="Detail")
template(v-once #default="scope") template(v-once #default="scope")
template(v-if="scope.row.type === 'GPS'") template(v-if="scope.row.type === 'GPS'")
location(v-if="scope.row.location[0]" :location="scope.row.location[0]") location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName")
template(v-else-if="scope.row.type === 'Offline' || scope.row.type === 'Online'") template(v-else-if="scope.row.type === 'Offline' || scope.row.type === 'Online'")
location(v-if="scope.row.location" :location="scope.row.location") location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName")
template(v-else-if="scope.row.type === 'Status'") template(v-else-if="scope.row.type === 'Status'")
el-tooltip(placement="top") el-tooltip(placement="top")
template(#content) template(#content)
span(v-if="scope.row.status[0].status === 'active'") Online span(v-if="scope.row.status === 'active'") Online
span(v-else-if="scope.row.status[0].status === 'join me'") Join Me span(v-else-if="scope.row.status === 'join me'") Join Me
span(v-else-if="scope.row.status[0].status === 'ask me'") Ask Me span(v-else-if="scope.row.status === 'ask me'") Ask Me
span(v-else-if="scope.row.status[0].status === 'busy'") Do Not Disturb span(v-else-if="scope.row.status === 'busy'") Do Not Disturb
span(v-else) Offline span(v-else) Offline
i.x-user-status(:class="userStatusClass(scope.row.status[0])") i.x-user-status(:class="statusClass(scope.row.status)")
span(v-text="scope.row.status[0].statusDescription") span(v-text="scope.row.statusDescription")
template(v-else-if="scope.row.type === 'Avatar'") template(v-else-if="scope.row.type === 'Avatar'")
avatar-info(:imageurl="scope.row.avatar[0].currentAvatarImageUrl" :userid="scope.row.userId") avatar-info(:imageurl="scope.row.currentAvatarImageUrl" :userid="scope.row.userId" :hintownerid="scope.row.ownerId" :hintavatarname="scope.row.avatarName")
//- gameLog //- gameLog
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'gameLog'") .x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'gameLog'")

View File

@@ -0,0 +1,158 @@
import sqliteService from '../service/sqlite.js';
class Database {
async init() {
await sqliteService.executeNonQuery(
'CREATE TABLE IF NOT EXISTS feed_gps (id INTEGER PRIMARY KEY, created_at TEXT, user_id TEXT, display_name TEXT, location TEXT, world_name TEXT, previous_location TEXT, time INTEGER)'
);
await sqliteService.executeNonQuery(
'CREATE TABLE IF NOT EXISTS feed_status (id INTEGER PRIMARY KEY, created_at TEXT, user_id TEXT, display_name TEXT, status TEXT, status_description TEXT, previous_status TEXT, previous_status_description TEXT)'
);
await sqliteService.executeNonQuery(
'CREATE TABLE IF NOT EXISTS feed_avatar (id INTEGER PRIMARY KEY, created_at TEXT, user_id TEXT, display_name TEXT, owner_id TEXT, avatar_name TEXT, current_avatar_image_url TEXT, current_avatar_thumbnail_image_url TEXT, previous_current_avatar_image_url TEXT, previous_current_avatar_thumbnail_image_url TEXT)'
);
await sqliteService.executeNonQuery(
'CREATE TABLE IF NOT EXISTS feed_online_offline (id INTEGER PRIMARY KEY, created_at TEXT, user_id TEXT, display_name TEXT, type TEXT, location TEXT, world_name TEXT, time INTEGER)'
);
}
async getFeedDatabase() {
var feedDatabase = [];
await sqliteService.execute((dbRow) => {
var row = {
created_at: dbRow[1],
userId: dbRow[2],
displayName: dbRow[3],
type: 'GPS',
location: dbRow[4],
worldName: dbRow[5],
previousLocation: dbRow[6],
time: dbRow[7]
};
feedDatabase.unshift(row);
}, 'SELECT * FROM feed_gps');
await sqliteService.execute((dbRow) => {
var row = {
created_at: dbRow[1],
userId: dbRow[2],
displayName: dbRow[3],
type: 'Status',
status: dbRow[4],
statusDescription: dbRow[5],
previousStatus: dbRow[6],
previousStatusDescription: dbRow[7]
};
feedDatabase.unshift(row);
}, 'SELECT * FROM feed_status');
await sqliteService.execute((dbRow) => {
var row = {
created_at: dbRow[1],
userId: dbRow[2],
displayName: dbRow[3],
type: 'Avatar',
ownerId: dbRow[4],
avatarName: dbRow[5],
currentAvatarImageUrl: dbRow[6],
currentAvatarThumbnailImageUrl: dbRow[7],
previousCurrentAvatarImageUrl: dbRow[8],
previousCurrentAvatarThumbnailImageUrl: dbRow[9]
};
feedDatabase.unshift(row);
}, 'SELECT * FROM feed_avatar');
await sqliteService.execute((dbRow) => {
var row = {
created_at: dbRow[1],
userId: dbRow[2],
displayName: dbRow[3],
type: dbRow[4],
location: dbRow[5],
worldName: dbRow[6],
time: dbRow[7]
};
feedDatabase.unshift(row);
}, 'SELECT * FROM feed_online_offline');
var compareByCreatedAt = function (a, b) {
var A = a.created_at;
var B = b.created_at;
if (A < B) {
return -1;
}
if (A > B) {
return 1;
}
return 0;
};
feedDatabase.sort(compareByCreatedAt);
return feedDatabase;
}
addGPSToDatabase(entry) {
sqliteService.executeNonQuery(
'INSERT OR IGNORE INTO feed_gps (created_at, user_id, display_name, location, world_name, previous_location, time) VALUES (@created_at, @user_id, @display_name, @location, @world_name, @previous_location, @time)',
{
'@created_at': entry.created_at,
'@user_id': entry.userId,
'@display_name': entry.displayName,
'@location': entry.location,
'@world_name': entry.worldName,
'@previous_location': entry.previousLocation,
'@time': entry.time
}
);
}
addStatusToDatabase(entry) {
sqliteService.executeNonQuery(
'INSERT OR IGNORE INTO feed_status (created_at, user_id, display_name, status, status_description, previous_status, previous_status_description) VALUES (@created_at, @user_id, @display_name, @status, @status_description, @previous_status, @previous_status_description)',
{
'@created_at': entry.created_at,
'@user_id': entry.userId,
'@display_name': entry.displayName,
'@status': entry.status,
'@status_description': entry.statusDescription,
'@previous_status': entry.previousStatus,
'@previous_status_description': entry.previousStatusDescription
}
);
}
addAvatarToDatabase(entry) {
sqliteService.executeNonQuery(
'INSERT OR IGNORE INTO feed_avatar (created_at, user_id, display_name, owner_id, avatar_name, current_avatar_image_url, current_avatar_thumbnail_image_url, previous_current_avatar_image_url, previous_current_avatar_thumbnail_image_url) VALUES (@created_at, @user_id, @display_name, @owner_id, @avatar_name, @current_avatar_image_url, @current_avatar_thumbnail_image_url, @previous_current_avatar_image_url, @previous_current_avatar_thumbnail_image_url)',
{
'@created_at': entry.created_at,
'@user_id': entry.userId,
'@display_name': entry.displayName,
'@owner_id': entry.ownerId,
'@avatar_name': entry.avatarName,
'@current_avatar_image_url': entry.currentAvatarImageUrl,
'@current_avatar_thumbnail_image_url': entry.currentAvatarThumbnailImageUrl,
'@previous_current_avatar_image_url': entry.previousCurrentAvatarImageUrl,
'@previous_current_avatar_thumbnail_image_url': entry.previousCurrentAvatarThumbnailImageUrl
}
);
}
addOnlineOfflineToDatabase(entry) {
sqliteService.executeNonQuery(
'INSERT OR IGNORE INTO feed_online_offline (created_at, user_id, display_name, type, location, world_name, time) VALUES (@created_at, @user_id, @display_name, @type, @location, @world_name, @time)',
{
'@created_at': entry.created_at,
'@user_id': entry.userId,
'@display_name': entry.displayName,
'@type': entry.type,
'@location': entry.location,
'@world_name': entry.worldName,
'@time': entry.time
}
);
}
}
var self = new Database();
window.database = self;
export {
self as default,
Database
};

View File

@@ -481,24 +481,10 @@ speechSynthesis.getVoices();
this.text = this.hint; this.text = this.hint;
} }
} else if (L.worldId) { } else if (L.worldId) {
var ref = API.cachedWorlds.get(L.worldId); if (L.instanceId) {
if (typeof ref === 'undefined') { this.text = ` #${L.instanceName} ${L.accessType}`;
API.getWorld({
worldId: L.worldId
}).then((args) => {
if (L.tag === this.location) {
if (L.instanceId) {
this.text = `${args.json.name} #${L.instanceName} ${L.accessType}`;
} else {
this.text = args.json.name;
}
}
return args;
});
} else if (L.instanceId) {
this.text = `${ref.name} #${L.instanceName} ${L.accessType}`;
} else { } else {
this.text = ref.name; this.text = this.location;
} }
} }
this.region = ''; this.region = '';
@@ -864,7 +850,7 @@ speechSynthesis.getVoices();
} }
}; };
$app.methods.updateSharedFeedNoty = async function (notyFeed) { $app.methods.updateSharedFeedNoty = function (notyFeed) {
var notyToPlay = []; var notyToPlay = [];
notyFeed.forEach((feed) => { notyFeed.forEach((feed) => {
var displayName = ''; var displayName = '';
@@ -916,7 +902,7 @@ speechSynthesis.getVoices();
text = `<strong>${noty.displayName}</strong> is joining`; text = `<strong>${noty.displayName}</strong> is joining`;
break; break;
case 'GPS': case 'GPS':
text = `<strong>${noty.displayName}</strong> is in ${await this.displayLocation(noty.location[0])}`; text = `<strong>${noty.displayName}</strong> is in ${this.displayLocation(noty.location, noty.worldName)}`;
break; break;
case 'Online': case 'Online':
text = `<strong>${noty.displayName}</strong> has logged in`; text = `<strong>${noty.displayName}</strong> has logged in`;
@@ -925,7 +911,7 @@ speechSynthesis.getVoices();
text = `<strong>${noty.displayName}</strong> has logged out`; text = `<strong>${noty.displayName}</strong> has logged out`;
break; break;
case 'Status': case 'Status':
text = `<strong>${noty.displayName}</strong> status is now <i>${noty.status[0].status}</i> ${noty.status[0].statusDescription}`; text = `<strong>${noty.displayName}</strong> status is now <i>${noty.status}</i> ${noty.statusDescription}`;
break; break;
case 'invite': case 'invite':
text = `<strong>${noty.senderUsername}</strong> has invited you to ${noty.details.worldName} ${message}`; text = `<strong>${noty.senderUsername}</strong> has invited you to ${noty.details.worldName} ${message}`;
@@ -991,25 +977,19 @@ speechSynthesis.getVoices();
} }
}; };
$app.methods.userStatusClass = function (user) { $app.methods.statusClass = function (status) {
var style = {}; var style = {};
if (typeof user !== 'undefined') { if (typeof status !== 'undefined') {
if (user.location === 'offline') { if (status === 'active') {
// Offline
style.offline = true;
} else if (user.state === 'active') {
// Active
style.active = true;
} else if (user.status === 'active') {
// Online // Online
style.online = true; style.online = true;
} else if (user.status === 'join me') { } else if (status === 'join me') {
// Join Me // Join Me
style.joinme = true; style.joinme = true;
} else if (user.status === 'ask me') { } else if (status === 'ask me') {
// Ask Me // Ask Me
style.askme = true; style.askme = true;
} else if (user.status === 'busy') { } else if (status === 'busy') {
// Do Not Disturb // Do Not Disturb
style.busy = true; style.busy = true;
} }
@@ -1017,7 +997,7 @@ speechSynthesis.getVoices();
return style; return style;
}; };
$app.methods.displayLocation = async function (location) { $app.methods.displayLocation = function (location, worldName) {
var text = ''; var text = '';
var L = API.parseLocation(location); var L = API.parseLocation(location);
if (L.isOffline) { if (L.isOffline) {
@@ -1025,23 +1005,10 @@ speechSynthesis.getVoices();
} else if (L.isPrivate) { } else if (L.isPrivate) {
text = 'Private'; text = 'Private';
} else if (L.worldId) { } else if (L.worldId) {
var ref = API.cachedWorlds.get(L.worldId); if (L.instanceId) {
if (typeof ref === 'undefined') { text = `${worldName} ${L.accessType}`;
await API.getWorld({
worldId: L.worldId
}).then((args) => {
if (L.tag === location) {
if (L.instanceId) {
text = `${args.json.name} ${L.accessType}`;
} else {
text = args.json.name;
}
}
});
} else if (L.instanceId) {
text = `${ref.name} ${L.accessType}`;
} else { } else {
text = ref.name; text = worldName;
} }
} }
return text; return text;

View File

@@ -21,7 +21,7 @@ html
.detail .detail
span.extra span.extra
span.time {{ feed.created_at | formatDate('HH:MI') }} span.time {{ feed.created_at | formatDate('HH:MI') }}
| #[span.name(v-text="feed.displayName")] #[location(:location="feed.location[0]")] | #[span.name(v-text="feed.displayName")] #[location(:location="feed.location" :hint="feed.worldName")]
div(v-else-if="feed.type === 'Offline'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") div(v-else-if="feed.type === 'Offline'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
.detail .detail
span.extra span.extra
@@ -36,7 +36,7 @@ html
.detail .detail
span.extra span.extra
span.time {{ feed.created_at | formatDate('HH:MI') }} span.time {{ feed.created_at | formatDate('HH:MI') }}
| #[span.name(v-text="feed.displayName")] #[i.x-user-status(:class="userStatusClass(feed.status[0])")] {{feed.status[0].statusDescription}} | #[span.name(v-text="feed.displayName")] #[i.x-user-status(:class="statusClass(feed.status)")] {{feed.statusDescription}}
div(v-else-if="feed.type === 'OnPlayerJoined'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }") div(v-else-if="feed.type === 'OnPlayerJoined'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
.detail .detail
span.extra span.extra