diff --git a/src/components/dialogs/UserDialog/UserDialog.vue b/src/components/dialogs/UserDialog/UserDialog.vue index 9c49851a..0561430a 100644 --- a/src/components/dialogs/UserDialog/UserDialog.vue +++ b/src/components/dialogs/UserDialog/UserDialog.vue @@ -42,6 +42,10 @@ + + + + tab.value === 'JSON'); + tabs.splice(jsonIdx, 0, { value: 'Activity', label: t('dialog.user.activity.header') }); + } return tabs; }); const infoTabRef = ref(null); + const activityTabRef = ref(null); const favoriteWorldsTabRef = ref(null); const mutualFriendsTabRef = ref(null); const worldsTabRef = ref(null); @@ -326,6 +337,8 @@ userDialogLastFavoriteWorld.value = userId; favoriteWorldsTabRef.value?.getUserFavoriteWorlds(userId); } + } else if (tabName === 'Activity') { + activityTabRef.value?.loadOnlineFrequency(userId); } else if (tabName === 'JSON') { refreshUserDialogTreeData(); } @@ -335,7 +348,14 @@ * */ function loadLastActiveTab() { - handleUserDialogTab(userDialog.value.lastActiveTab); + let tab = userDialog.value.lastActiveTab; + // Activity tab is not available for own profile; fall back to Info + if (tab === 'Activity' && userDialog.value.id === currentUser.value.id) { + tab = 'Info'; + userDialog.value.lastActiveTab = 'Info'; + userDialog.value.activeTab = 'Info'; + } + handleUserDialogTab(tab); } /** diff --git a/src/components/dialogs/UserDialog/UserDialogActivityTab.vue b/src/components/dialogs/UserDialog/UserDialogActivityTab.vue new file mode 100644 index 00000000..c03e1147 --- /dev/null +++ b/src/components/dialogs/UserDialog/UserDialogActivityTab.vue @@ -0,0 +1,363 @@ + + + + + + + + + + {{ t('dialog.user.activity.total_events', { count: totalOnlineEvents }) }} + + + + + + {{ t('dialog.user.activity.most_active_day') }} + {{ peakDayText }} + + + {{ t('dialog.user.activity.most_active_time') }} + {{ peakTimeText }} + + + + + + + + + + + diff --git a/src/localization/en.json b/src/localization/en.json index 20519eaf..c0073c9c 100644 --- a/src/localization/en.json +++ b/src/localization/en.json @@ -1280,6 +1280,23 @@ "friend_order": "Friend Order" } }, + "activity": { + "header": "Activity", + "total_events": "{count} online events", + "times_online": "times online", + "most_active_day": "Most active day:", + "most_active_time": "Peak hours:", + "days": { + "mon": "Mon", + "tue": "Tue", + "wed": "Wed", + "thu": "Thu", + "fri": "Fri", + "sat": "Sat", + "sun": "Sun" + }, + "easter_egg": "Did you farm your green squares today?" + }, "note_memo": { "header": "Edit Note And Memo", "cancel": "Cancel", diff --git a/src/services/database/feed.js b/src/services/database/feed.js index fb921844..daa231a8 100644 --- a/src/services/database/feed.js +++ b/src/services/database/feed.js @@ -572,6 +572,18 @@ const feed = { args ); return feedDatabase; + }, + + async getOnlineFrequencyData(userId) { + const data = []; + await sqliteService.execute( + (dbRow) => { + data.push(dbRow[0]); + }, + `SELECT created_at FROM ${dbVars.userPrefix}_feed_online_offline WHERE type = 'Online' AND user_id = @userId ORDER BY created_at`, + { '@userId': userId } + ); + return data; } };