diff --git a/public/index.html b/public/index.html index 30d9edf76..ccdf2a99d 100644 --- a/public/index.html +++ b/public/index.html @@ -2566,6 +2566,9 @@ + @@ -2604,7 +2607,6 @@

- diff --git a/public/script.js b/public/script.js index 944fd24a6..3cac2fbd1 100644 --- a/public/script.js +++ b/public/script.js @@ -1,4 +1,5 @@ -import { humanizedDateTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, AA_CountCharTime } from "./scripts/RossAscends-mods.js"; +import { humanizedDateTime, humanizeGenTime, favsToHotswap, getMessageTimeStamp, dragElement, isMobile, AA_CountCharTime } from "./scripts/RossAscends-mods.js"; +import { userStatsHandler, characterStatsHandler } from './scripts/stats.js'; import { encode } from "../scripts/gpt-2-3-tokenizer/mod.js"; import { GPT3BrowserTokenizer } from "../scripts/gpt-3-tokenizer/gpt3-tokenizer.js"; import { @@ -955,7 +956,7 @@ async function getCharacters() { updateCharacterCount('#rm_print_characters_block > div'); - await AA_CountCharTime(this_chid); + //await AA_CountCharTime(this_chid); } } @@ -4895,7 +4896,6 @@ async function getSettings(type) { } const data = await response.json(); - getStats(); if (data.result != "file not find" && data.settings) { settings = JSON.parse(data.settings); if (settings.username !== undefined) { @@ -5122,25 +5122,6 @@ async function saveSettings(type) { } -async function getStats() { - const response = await fetch("/getstats", { - method: "POST", - headers: getRequestHeaders(), - body: JSON.stringify({}), - cache: "no-cache", - }); - - if (!response.ok) { - toastr.error('Stats could not be loaded. Try reloading the page.'); - throw new Error('Error getting stats'); - } - - const data = await response.json(); - charStats = data; - console.log(charStats); - -} - function setCharacterBlockHeight() { const $children = $("#rm_print_characters_block").children(); @@ -8581,6 +8562,10 @@ $(document).ready(function () { restoreCaretPosition($(this).get(0), caretPosition); }); + $(".user_stats_button").on('click', function () { + userStatsHandler(charStats); + }); + $('#external_import_button').on('click', async () => { const html = `

Enter the URL of the content to import

Supported sources:
@@ -8719,4 +8704,4 @@ $(document).ready(function () { $("#charListGridToggle").on('click', async () => { doCharListDisplaySwitch(); }); -}) +}); \ No newline at end of file diff --git a/public/scripts/RossAscends-mods.js b/public/scripts/RossAscends-mods.js index b551a85e0..fd67afa37 100644 --- a/public/scripts/RossAscends-mods.js +++ b/public/scripts/RossAscends-mods.js @@ -16,6 +16,10 @@ import { charStats, } from "../script.js"; +import { + characterStatsHandler, +} from "./stats.js"; + import { power_user, @@ -72,7 +76,7 @@ const observer = new MutationObserver(function (mutations) { RA_checkOnlineStatus(); } else if (mutation.target.parentNode === SelectedCharacterTab) { setTimeout(RA_CountCharTokens, 200); - setTimeout(AA_CountCharTime, 200); + //setTimeout(AA_CountCharTime, 200); } }); }); @@ -108,10 +112,10 @@ function waitForElement(querySelector, timeout) { //humanize character generation time -export function humanizeGenTime(character) { - let stat = charStats[character.avatar] +export function humanizeGenTime(total_gen_time) { + //convert time_spent to humanized format of "_ Hours, _ Minutes, _ Seconds" from milliseconds - let time_spent = stat.total_gen_time + let time_spent = total_gen_time || 0; time_spent = Math.floor(time_spent / 1000); let seconds = time_spent % 60; time_spent = Math.floor(time_spent / 60); @@ -327,7 +331,10 @@ export function RA_CountCharTokens() { // if neither, probably safety char or some error in loading } else { console.debug("RA_TC -- no valid char found, closing."); } } - $("#result_info").html(`${count_tokens} Tokens (${perm_tokens} Permanent)`); + //label rm_stats_button with a tooltip indicating stats + $("#result_info").html(`${count_tokens} Tokens (${perm_tokens} Permanent) + + `); // display the counted tokens const tokenLimit = Math.max(((main_api !== 'openai' ? max_context : oai_settings.openai_max_context) / 2), 1024); if (count_tokens < tokenLimit && perm_tokens < tokenLimit) { @@ -339,10 +346,16 @@ export function RA_CountCharTokens() {
${count_tokens}
 Tokens (
${perm_tokens}
 Permanent)
+ `); + + } //warn if either are over 1024 + $(".rm_stats_button").on('click', function () { + characterStatsHandler(charStats, characters, this_chid); + }); } //Auto Load Last Charcter -- (fires when active_character is defined and auto_load_chat is true) async function RA_autoloadchat() { diff --git a/public/scripts/group-chats.js b/public/scripts/group-chats.js index 03e75092d..a325b6b43 100644 --- a/public/scripts/group-chats.js +++ b/public/scripts/group-chats.js @@ -1223,7 +1223,7 @@ function openCharacterDefinition(characterSelect) { select_selected_character(chid); // Gentle nudge to recalculate tokens RA_CountCharTokens(); - AA_CountCharTime(chid); + //AA_CountCharTime(chid); // Do a little tomfoolery to spoof the tag selector applyTagsOnCharacterSelect.call(characterSelect); } diff --git a/public/scripts/stats.js b/public/scripts/stats.js new file mode 100644 index 000000000..ce3261227 --- /dev/null +++ b/public/scripts/stats.js @@ -0,0 +1,98 @@ +// statsHelper.js +import { getRequestHeaders, callPopup, token } from '../script.js'; +import { humanizeGenTime } from './RossAscends-mods.js'; + + + +// Function for creating stat block HTML +function createStatBlock(statName, statValue) { + return `
+
${statName}:
+
${statValue}
+
`; +} + +function calculateTotal(stat) { + return isNaN(stat) ? 0 : stat; +} + +function calculateTotalStats(charStats) { + let totalStats = { + total_gen_time: 0, + user_msg_count: 0, + non_user_msg_count: 0, + user_word_count: 0, + non_user_word_count: 0, + total_swipe_count: 0 + }; + + for (let stats of Object.values(charStats)) { + totalStats.total_gen_time += calculateTotal(stats.total_gen_time); + totalStats.user_msg_count += calculateTotal(stats.user_msg_count); + totalStats.non_user_msg_count += calculateTotal(stats.non_user_msg_count); + totalStats.user_word_count += calculateTotal(stats.user_word_count); + totalStats.non_user_word_count += calculateTotal(stats.non_user_word_count); + totalStats.total_swipe_count += calculateTotal(stats.total_swipe_count); + } + + return totalStats; +} + +function createHtml(statsType, stats) { + // Get time string + let timeStirng = humanizeGenTime(stats.total_gen_time); + + // Create popup HTML with stats + let html = `

${statsType} Stats

`; + html += createStatBlock('Chat Time', timeStirng); + html += createStatBlock('Total User Messages', stats.user_msg_count); + html += createStatBlock('Total Character Messages', stats.non_user_msg_count); + html += createStatBlock('Total User Words', stats.user_word_count); + html += createStatBlock('Total Character Words', stats.non_user_word_count); + html += createStatBlock('Swipes', stats.total_swipe_count); + + callPopup(html, 'text'); +} + +async function userStatsHandler(charStats) { + // Get stats from server + let stats = await getStats(charStats); + + // Calculate total stats + let totalStats = calculateTotalStats(stats); + console.log(totalStats); + + // Create HTML with stats + createHtml('User', totalStats); +} + +async function characterStatsHandler(charStats, characters, this_chid) { + // Get stats from server + let stats = await getStats(charStats); + + // Get character stats + let myStats = stats[characters[this_chid].avatar]; + + // Create HTML with stats + createHtml('Character', myStats); +} + +async function getStats(charStats) { + const response = await fetch("/getstats", { + method: "POST", + headers: getRequestHeaders(), + body: JSON.stringify({}), + cache: "no-cache", + }); + + if (!response.ok) { + toastr.error('Stats could not be loaded. Try reloading the page.'); + throw new Error('Error getting stats'); + } + + const data = await response.json(); + return data; + +} + +export { userStatsHandler, characterStatsHandler, getStats }; diff --git a/public/style.css b/public/style.css index 3c48c434b..11ccf6a63 100644 --- a/public/style.css +++ b/public/style.css @@ -1877,6 +1877,11 @@ grammarly-extension { overflow-y: hidden; } +.rm_stat_block { + display: flex; + justify-content: space-between; +} + .large_dialogue_popup { height: 90vh !important; height: 90svh !important; diff --git a/statsHelpers.js b/statsHelpers.js index a4386157f..8195f4bd3 100644 --- a/statsHelpers.js +++ b/statsHelpers.js @@ -132,7 +132,6 @@ function countWordsInString(str) { * @return {object} An object containing the calculated statistics. */ const calculateStats = (chatsPath, item, index) => { - console.log('Calculating stats for', item); const char_dir = path.join(chatsPath, item.replace('.png', '')); let chat_size = 0; let date_last_chat = 0; @@ -152,7 +151,6 @@ const calculateStats = (chatsPath, item, index) => { const chats = fs.readdirSync(char_dir); if (Array.isArray(chats) && chats.length) { for (const chat of chats) { - console.log(uniqueGenStartTimes); const result = calculateTotalGenTimeAndWordCount(char_dir, chat, uniqueGenStartTimes); stats.total_gen_time += result.totalGenTime || 0; stats.user_word_count += result.userWordCount || 0; @@ -164,7 +162,6 @@ const calculateStats = (chatsPath, item, index) => { const chatStat = fs.statSync(path.join(char_dir, chat)); stats.chat_size += chatStat.size; stats.date_last_chat = Math.max(stats.date_last_chat, chatStat.mtimeMs); - console.log(stats); } } }