GameSentenceMiner 2.19.16__py3-none-any.whl → 2.20.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of GameSentenceMiner might be problematic. Click here for more details.

Files changed (70) hide show
  1. GameSentenceMiner/__init__.py +39 -0
  2. GameSentenceMiner/anki.py +6 -3
  3. GameSentenceMiner/gametext.py +13 -2
  4. GameSentenceMiner/gsm.py +40 -3
  5. GameSentenceMiner/locales/en_us.json +4 -0
  6. GameSentenceMiner/locales/ja_jp.json +4 -0
  7. GameSentenceMiner/locales/zh_cn.json +4 -0
  8. GameSentenceMiner/obs.py +4 -1
  9. GameSentenceMiner/owocr/owocr/ocr.py +304 -134
  10. GameSentenceMiner/owocr/owocr/run.py +1 -1
  11. GameSentenceMiner/ui/anki_confirmation.py +4 -2
  12. GameSentenceMiner/ui/config_gui.py +12 -0
  13. GameSentenceMiner/util/configuration.py +6 -2
  14. GameSentenceMiner/util/cron/__init__.py +12 -0
  15. GameSentenceMiner/util/cron/daily_rollup.py +613 -0
  16. GameSentenceMiner/util/cron/jiten_update.py +397 -0
  17. GameSentenceMiner/util/cron/populate_games.py +154 -0
  18. GameSentenceMiner/util/cron/run_crons.py +148 -0
  19. GameSentenceMiner/util/cron/setup_populate_games_cron.py +118 -0
  20. GameSentenceMiner/util/cron_table.py +334 -0
  21. GameSentenceMiner/util/db.py +236 -49
  22. GameSentenceMiner/util/ffmpeg.py +23 -4
  23. GameSentenceMiner/util/games_table.py +340 -93
  24. GameSentenceMiner/util/jiten_api_client.py +188 -0
  25. GameSentenceMiner/util/stats_rollup_table.py +216 -0
  26. GameSentenceMiner/web/anki_api_endpoints.py +438 -220
  27. GameSentenceMiner/web/database_api.py +955 -1259
  28. GameSentenceMiner/web/jiten_database_api.py +1015 -0
  29. GameSentenceMiner/web/rollup_stats.py +672 -0
  30. GameSentenceMiner/web/static/css/dashboard-shared.css +75 -13
  31. GameSentenceMiner/web/static/css/overview.css +604 -47
  32. GameSentenceMiner/web/static/css/search.css +226 -0
  33. GameSentenceMiner/web/static/css/shared.css +762 -0
  34. GameSentenceMiner/web/static/css/stats.css +221 -0
  35. GameSentenceMiner/web/static/js/components/bar-chart.js +339 -0
  36. GameSentenceMiner/web/static/js/database-bulk-operations.js +320 -0
  37. GameSentenceMiner/web/static/js/database-game-data.js +390 -0
  38. GameSentenceMiner/web/static/js/database-game-operations.js +213 -0
  39. GameSentenceMiner/web/static/js/database-helpers.js +44 -0
  40. GameSentenceMiner/web/static/js/database-jiten-integration.js +750 -0
  41. GameSentenceMiner/web/static/js/database-popups.js +89 -0
  42. GameSentenceMiner/web/static/js/database-tabs.js +64 -0
  43. GameSentenceMiner/web/static/js/database-text-management.js +371 -0
  44. GameSentenceMiner/web/static/js/database.js +86 -718
  45. GameSentenceMiner/web/static/js/goals.js +79 -18
  46. GameSentenceMiner/web/static/js/heatmap.js +29 -23
  47. GameSentenceMiner/web/static/js/overview.js +1205 -339
  48. GameSentenceMiner/web/static/js/regex-patterns.js +100 -0
  49. GameSentenceMiner/web/static/js/search.js +215 -18
  50. GameSentenceMiner/web/static/js/shared.js +193 -39
  51. GameSentenceMiner/web/static/js/stats.js +1536 -179
  52. GameSentenceMiner/web/stats.py +1142 -269
  53. GameSentenceMiner/web/stats_api.py +2104 -0
  54. GameSentenceMiner/web/templates/anki_stats.html +4 -18
  55. GameSentenceMiner/web/templates/components/date-range.html +118 -3
  56. GameSentenceMiner/web/templates/components/html-head.html +40 -6
  57. GameSentenceMiner/web/templates/components/js-config.html +8 -8
  58. GameSentenceMiner/web/templates/components/regex-input.html +160 -0
  59. GameSentenceMiner/web/templates/database.html +564 -117
  60. GameSentenceMiner/web/templates/goals.html +41 -5
  61. GameSentenceMiner/web/templates/overview.html +159 -129
  62. GameSentenceMiner/web/templates/search.html +78 -9
  63. GameSentenceMiner/web/templates/stats.html +159 -5
  64. GameSentenceMiner/web/texthooking_page.py +280 -111
  65. {gamesentenceminer-2.19.16.dist-info → gamesentenceminer-2.20.0.dist-info}/METADATA +43 -2
  66. {gamesentenceminer-2.19.16.dist-info → gamesentenceminer-2.20.0.dist-info}/RECORD +70 -47
  67. {gamesentenceminer-2.19.16.dist-info → gamesentenceminer-2.20.0.dist-info}/WHEEL +0 -0
  68. {gamesentenceminer-2.19.16.dist-info → gamesentenceminer-2.20.0.dist-info}/entry_points.txt +0 -0
  69. {gamesentenceminer-2.19.16.dist-info → gamesentenceminer-2.20.0.dist-info}/licenses/LICENSE +0 -0
  70. {gamesentenceminer-2.19.16.dist-info → gamesentenceminer-2.20.0.dist-info}/top_level.txt +0 -0
@@ -135,6 +135,14 @@
135
135
  </span>
136
136
  <span class="dashboard-stat-label">Characters Required</span>
137
137
  </div>
138
+ <div class="dashboard-stat-item goal-stat-item tooltip" data-tooltip="Your progress toward today's cards mined goal" id="cardsGoalItem" style="display: none;">
139
+ <span class="dashboard-stat-value">
140
+ <span id="todayCardsProgress">-</span>
141
+ <span class="goal-separator">/</span>
142
+ <span id="todayCardsRequired">-</span>
143
+ </span>
144
+ <span class="dashboard-stat-label">Cards Mined</span>
145
+ </div>
138
146
  </div>
139
147
 
140
148
  <div class="dashboard-progress-section" id="todayGoalsProgress" style="display: none;">
@@ -173,11 +181,11 @@
173
181
  <div class="dashboard-stats-grid" id="projectionStats">
174
182
  <div class="dashboard-stat-item tooltip" data-tooltip="Total hours you'll have by your target date" id="hoursProjectionItem" style="display: none;">
175
183
  <span class="dashboard-stat-value" id="projectionHoursValue">-</span>
176
- <span class="dashboard-stat-label">Total Hours by Target</span>
184
+ <span class="dashboard-stat-label" id="hoursProjectionLabel">Total Hours by Target</span>
177
185
  </div>
178
186
  <div class="dashboard-stat-item tooltip" data-tooltip="Total characters you'll have by your target date" id="charsProjectionItem" style="display: none;">
179
187
  <span class="dashboard-stat-value" id="projectionCharsValue">-</span>
180
- <span class="dashboard-stat-label">Total Characters by Target</span>
188
+ <span class="dashboard-stat-label" id="charsProjectionLabel">Total Characters by Target</span>
181
189
  </div>
182
190
  <div class="dashboard-stat-item tooltip" data-tooltip="Total games you'll have by your target date" id="gamesProjectionItem" style="display: none;">
183
191
  <span class="dashboard-stat-value" id="projectionGamesValue">-</span>
@@ -287,12 +295,12 @@
287
295
  style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
288
296
  Games/Visual Novels Target
289
297
  </label>
290
- <input type="number" id="gamesTarget" name="games_target" min="1" max="1000"
298
+ <input type="number" id="gamesTarget" name="games_target" min="0" max="1000"
291
299
  style="width: 90%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
292
300
  placeholder="100">
293
301
  <small
294
302
  style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
295
- Number of games/visual novels to complete (1-1,000) - Default: 100
303
+ Number of games/visual novels to complete (0-1,000) - Set to 0 to hide this goal - Default: 100
296
304
  </small>
297
305
  </div>
298
306
 
@@ -310,6 +318,32 @@
310
318
  </small>
311
319
  </div>
312
320
  </div>
321
+
322
+ <!-- Daily Goals Section -->
323
+ <div style="margin-bottom: 20px;">
324
+ <label
325
+ style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
326
+ Daily Goals Configuration
327
+ </label>
328
+ <p style="color: var(--text-secondary); margin-bottom: 20px; font-size: 14px;">
329
+ Set your daily targets for tracking progress.
330
+ </p>
331
+
332
+ <div style="margin-bottom: 15px;">
333
+ <label for="cardsMinedDailyTarget"
334
+ style="display: block; font-weight: 600; margin-bottom: 8px; color: var(--text-primary);">
335
+ Cards Mined Daily Target
336
+ </label>
337
+ <input type="number" id="cardsMinedDailyTarget" name="cards_mined_daily_target" min="0"
338
+ max="1000"
339
+ style="width: 90%; padding: 10px; border: 1px solid var(--border-color); border-radius: 5px; background: var(--bg-tertiary); color: var(--text-primary); font-size: 14px;"
340
+ placeholder="10">
341
+ <small
342
+ style="color: var(--text-tertiary); font-size: 12px; margin-top: 4px; display: block;">
343
+ Number of cards to mine per day (0-1,000) - Default: 10 cards
344
+ </small>
345
+ </div>
346
+ </div>
313
347
  </form>
314
348
 
315
349
  <div id="settingsError"
@@ -333,6 +367,7 @@
333
367
  {% set hours_target_date = stats_config.reading_hours_target_date | default('') %}
334
368
  {% set chars_target_date = stats_config.character_count_target_date | default('') %}
335
369
  {% set games_target_date = stats_config.games_target_date | default('') %}
370
+ {% set cards_daily_target = stats_config.cards_mined_daily_target | default(10) %}
336
371
 
337
372
  {% set stats_config_vars = {
338
373
  'readingHoursTarget': hours_target,
@@ -340,7 +375,8 @@
340
375
  'gamesTarget': games_target,
341
376
  'readingHoursTargetDate': hours_target_date,
342
377
  'characterCountTargetDate': chars_target_date,
343
- 'gamesTargetDate': games_target_date
378
+ 'gamesTargetDate': games_target_date,
379
+ 'cardsMinedDailyTarget': cards_daily_target
344
380
  } %}
345
381
 
346
382
  <!-- Include shared JavaScript configuration -->
@@ -14,62 +14,180 @@
14
14
  {% include 'components/navigation.html' %}
15
15
 
16
16
  <!-- Include shared date range component -->
17
- {% include 'components/date-range.html' %}
17
+ {# {% include 'components/date-range.html' %} #}
18
18
 
19
19
  <!-- Include shared popup components -->
20
20
  {% include 'components/popups.html' %}
21
21
 
22
- <!-- Dashboard Statistics Sections -->
23
- <div class="dashboard-container">
24
- <!-- Current Game Statistics Panel -->
25
- <div class="dashboard-card current-game" id="currentGameCard">
26
- <div class="dashboard-card-header">
27
- <div>
28
- <h3 class="dashboard-card-title">
29
- <span class="dashboard-card-icon">🎮</span>
30
- Current Game Statistics
31
- </h3>
32
- <p class="dashboard-card-subtitle" id="currentGameName">Loading...</p>
22
+ <!-- Current Game Statistics Panel - Full Width -->
23
+ <div class="dashboard-card current-game-full-width" id="currentGameCard">
24
+ <div class="dashboard-card-header">
25
+ <div>
26
+ <h3 class="dashboard-card-title">
27
+ <span class="dashboard-card-icon">🎮</span>
28
+ Today's Sessions
29
+ </h3>
30
+ <p class="dashboard-card-subtitle" id="currentGameName">Loading...</p>
31
+ </div>
32
+ <div class="dashboard-header-actions">
33
+ <!-- Session Navigation -->
34
+ <div class="session-navigation">
35
+ <button class="prev-session-btn" data-action="prevSession">←</button>
36
+ <button class="next-session-btn" data-action="nextSession">→</button>
37
+ <button class="delete-session-btn" data-action="deleteSession" title="Delete Current Session">🗑️</button>
33
38
  </div>
39
+ <button class="game-completion-btn" id="gameCompletionBtn" style="display: none;">
40
+ Mark as completed?
41
+ </button>
34
42
  <div class="dashboard-streak-indicator" id="currentGameStreak" style="display: none;">
35
43
  <span id="currentStreakValue">0</span> day streak
36
44
  </div>
37
45
  </div>
46
+ </div>
38
47
 
39
- <div class="dashboard-stats-grid" id="currentGameStats">
40
- <div class="dashboard-stat-item tooltip" data-tooltip="Total characters read in this game">
41
- <span class="dashboard-stat-value" id="currentTotalChars">-</span>
42
- <span class="dashboard-stat-label">Characters</span>
48
+ <!-- No Game Data Message -->
49
+ <div class="no-game-data-message" id="noGameDataMessage" style="display: none; text-align: center; padding: 20px; color: var(--text-secondary);">
50
+ <p><strong id="noGameDataTitle"></strong> not found. Please link this to Jiten or create it manually in <a href="http://localhost:55000/database" style="color: var(--primary-color); text-decoration: underline;">Database Management</a></p>
51
+ </div>
52
+
53
+ <!-- Game Content Grid: Photo + Info -->
54
+ <div class="game-content-grid" id="gameContentGrid" style="display: none;">
55
+ <div class="game-photo-section" id="gamePhotoSection">
56
+ <img id="gamePhoto" src="" alt="Game Cover" class="game-photo-img" onerror="this.style.display='none'; this.parentElement.style.display='none';">
57
+ </div>
58
+ <div class="game-info-section">
59
+ <div class="game-header-row">
60
+ <div class="game-titles">
61
+ <div class="game-title-original" id="gameTitleOriginal"></div>
62
+ <div class="game-title-romaji" id="gameTitleRomaji"></div>
63
+ <div class="game-title-english" id="gameTitleEnglish"></div>
64
+ </div>
65
+ <div class="game-type-badge" id="gameTypeBadge" style="display: none;"></div>
43
66
  </div>
44
- <div class="dashboard-stat-item tooltip" data-tooltip="Total time spent reading this game">
45
- <span class="dashboard-stat-value" id="currentTotalTime">-</span>
46
- <span class="dashboard-stat-label">Time Spent</span>
67
+ <div class="game-description-container">
68
+ <div class="game-description" id="gameDescription"></div>
69
+ <button class="description-expand-btn" id="descriptionExpandBtn" style="display: none;">
70
+ <span class="expand-text">Show more</span>
71
+ <span class="collapse-text" style="display: none;">Show less</span>
72
+ </button>
47
73
  </div>
48
- <div class="dashboard-stat-item tooltip" data-tooltip="Average reading speed for this game">
49
- <span class="dashboard-stat-value" id="currentReadingSpeed">-</span>
50
- <span class="dashboard-stat-label">Chars/Hour</span>
74
+ <div class="game-links-container" id="gameLinksContainer" style="display: none;">
75
+ <div class="game-links-label">🔗 Links:</div>
76
+ <div class="game-links-pills" id="gameLinksPills"></div>
51
77
  </div>
52
- <div class="dashboard-stat-item tooltip" data-tooltip="Number of reading sessions for this game">
53
- <span class="dashboard-stat-value" id="currentSessions">-</span>
54
- <span class="dashboard-stat-label">Sessions</span>
78
+ <div class="game-progress-container" id="gameProgressContainer" style="display: none;">
79
+ <div class="game-progress-header">
80
+ <span class="game-progress-label">Completion</span>
81
+ <span class="game-progress-percentage" id="gameProgressPercentage">0%</span>
82
+ </div>
83
+ <div class="game-progress-timeline">
84
+ <span class="game-progress-date start-date" id="gameStartDate">-</span>
85
+ <div class="game-progress-bar">
86
+ <div class="game-progress-fill" id="gameProgressFill"></div>
87
+ </div>
88
+ <span class="game-progress-date end-date" id="gameEstimatedEndDate">-</span>
89
+ </div>
55
90
  </div>
56
91
  </div>
92
+ </div>
57
93
 
58
- <div class="dashboard-progress-section">
59
- <div class="dashboard-progress-title">Recent Progress</div>
60
- <div class="dashboard-progress-items">
61
- <div class="dashboard-progress-item">
62
- <div class="dashboard-progress-value positive" id="currentMonthlyChars">-</div>
63
- <div class="dashboard-progress-label">Monthly Characters</div>
64
- </div>
65
- <div class="dashboard-progress-item">
66
- <div class="dashboard-progress-value neutral" id="currentFirstDate">-</div>
67
- <div class="dashboard-progress-label">Started</div>
68
- </div>
69
- <div class="dashboard-progress-item">
70
- <div class="dashboard-progress-value neutral" id="currentLastDate">-</div>
71
- <div class="dashboard-progress-label">Last Activity</div>
72
- </div>
94
+ <!-- Overall Game Statistics -->
95
+ <div class="stats-section-header">
96
+ <span class="stats-section-icon">📊</span>
97
+ <h4 class="stats-section-title">Overall Game Statistics</h4>
98
+ </div>
99
+ <div class="dashboard-stats-grid" id="currentGameStats">
100
+ <div class="dashboard-stat-item tooltip" data-tooltip="Total characters read in this game">
101
+ <span class="dashboard-stat-value" id="currentTotalChars">-</span>
102
+ <span class="dashboard-stat-label">Characters</span>
103
+ </div>
104
+ <div class="dashboard-stat-item tooltip" data-tooltip="Average reading speed for this game">
105
+ <span class="dashboard-stat-value" id="currentReadingSpeed">-</span>
106
+ <span class="dashboard-stat-label">Chars/Hour</span>
107
+ </div>
108
+ <div class="dashboard-stat-item tooltip" data-tooltip="Total time spent reading this game">
109
+ <span class="dashboard-stat-value" id="currentTotalTime">-</span>
110
+ <span class="dashboard-stat-label">Time Spent</span>
111
+ </div>
112
+ <div class="dashboard-stat-item tooltip" data-tooltip="Estimated time remaining to complete this game">
113
+ <span class="dashboard-stat-value" id="currentEstimatedTimeLeft">-</span>
114
+ <span class="dashboard-stat-label">Est. Time Left</span>
115
+ </div>
116
+ </div>
117
+
118
+ <!-- Current Session Statistics -->
119
+ <div class="stats-section-header" style="margin-top: 24px;">
120
+ <span class="stats-section-icon">⏱️</span>
121
+ <h4 class="stats-section-title">Current Session Statistics</h4>
122
+ </div>
123
+ <div class="dashboard-stats-grid" id="currentSessionStats" style="margin-top: 12px;">
124
+ <div class="dashboard-stat-item tooltip" data-tooltip="Total hours spent reading in current session">
125
+ <span class="dashboard-stat-value" id="currentSessionTotalHours">-</span>
126
+ <span class="dashboard-stat-label">Session Hours</span>
127
+ </div>
128
+ <div class="dashboard-stat-item tooltip" data-tooltip="Total characters read in current session">
129
+ <span class="dashboard-stat-value" id="currentSessionTotalChars">-</span>
130
+ <span class="dashboard-stat-label">Session Chars</span>
131
+ </div>
132
+ <div class="dashboard-stat-item tooltip" data-tooltip="Session start time">
133
+ <span class="dashboard-stat-value" id="currentSessionStartTime">-</span>
134
+ <span class="dashboard-stat-label">Started</span>
135
+ </div>
136
+ <div class="dashboard-stat-item tooltip" data-tooltip="Session end time">
137
+ <span class="dashboard-stat-value" id="currentSessionEndTime">-</span>
138
+ <span class="dashboard-stat-label">Ended</span>
139
+ </div>
140
+ <div class="dashboard-stat-item tooltip" data-tooltip="Average reading speed in current session">
141
+ <span class="dashboard-stat-value" id="currentSessionCharsPerHour">-</span>
142
+ <span class="dashboard-stat-label">Session Chars/Hour</span>
143
+ </div>
144
+ </div>
145
+ </div>
146
+
147
+ <!-- Loading/Error states for dashboard -->
148
+ <div class="dashboard-loading" id="dashboardLoading" style="display: none;">
149
+ <div class="spinner"></div>
150
+ <span>Loading dashboard statistics...</span>
151
+ </div>
152
+
153
+ <div class="dashboard-error" id="dashboardError" style="display: none;">
154
+ <div class="dashboard-error-icon">⚠️</div>
155
+ <div class="dashboard-error-message">Failed to load dashboard statistics</div>
156
+ <button class="dashboard-retry-btn" data-action="loadDashboardData">Retry</button>
157
+ </div>
158
+
159
+ <div class="chart-container">
160
+ <h2>Activity Heatmap</h2>
161
+ <div id="heatmapContainer"></div>
162
+ </div>
163
+
164
+ <!-- Dashboard Statistics Sections -->
165
+ <div class="dashboard-container">
166
+ <!-- Today's Overview Card -->
167
+ <div class="dashboard-card today-overview" id="todayOverviewCard">
168
+ <div class="dashboard-card-header">
169
+ <h3 class="dashboard-card-title">
170
+ <span class="dashboard-card-icon">📅</span>
171
+ Today's Overview
172
+ </h3>
173
+ <p class="dashboard-card-subtitle" id="todayDate">Loading...</p>
174
+ </div>
175
+ <div class="dashboard-stats-grid" id="todayStats">
176
+ <div class="dashboard-stat-item tooltip" data-tooltip="Total hours spent reading today">
177
+ <span class="dashboard-stat-value" id="todayTotalHours">-</span>
178
+ <span class="dashboard-stat-label">Hours Spent</span>
179
+ </div>
180
+ <div class="dashboard-stat-item tooltip" data-tooltip="Total characters read today">
181
+ <span class="dashboard-stat-value" id="todayTotalChars">-</span>
182
+ <span class="dashboard-stat-label">Characters</span>
183
+ </div>
184
+ <div class="dashboard-stat-item tooltip" data-tooltip="Number of reading sessions today">
185
+ <span class="dashboard-stat-value" id="todaySessions">-</span>
186
+ <span class="dashboard-stat-label">Sessions</span>
187
+ </div>
188
+ <div class="dashboard-stat-item tooltip" data-tooltip="Average reading speed today">
189
+ <span class="dashboard-stat-value" id="todayCharsPerHour">-</span>
190
+ <span class="dashboard-stat-label">Chars/Hour</span>
73
191
  </div>
74
192
  </div>
75
193
  </div>
@@ -111,13 +229,9 @@
111
229
  <div class="dashboard-progress-section">
112
230
  <div class="dashboard-progress-title">Overall Progress</div>
113
231
  <div class="dashboard-progress-items">
114
- <div class="dashboard-progress-item">
115
- <div class="dashboard-progress-value positive" id="allMonthlyChars">-</div>
116
- <div class="dashboard-progress-label">Monthly Characters</div>
117
- </div>
118
232
  <div class="dashboard-progress-item">
119
233
  <div class="dashboard-progress-value neutral" id="allUniqueGames">-</div>
120
- <div class="dashboard-progress-label">Games Played</div>
234
+ <div class="dashboard-progress-label">Games Completed</div>
121
235
  </div>
122
236
  <div class="dashboard-progress-item">
123
237
  <div class="dashboard-progress-value neutral" id="allTotalSentences">-</div>
@@ -128,91 +242,7 @@
128
242
  </div>
129
243
  </div>
130
244
 
131
- <!-- Loading/Error states for dashboard -->
132
- <div class="dashboard-loading" id="dashboardLoading" style="display: none;">
133
- <div class="spinner"></div>
134
- <span>Loading dashboard statistics...</span>
135
- </div>
136
-
137
- <div class="dashboard-error" id="dashboardError" style="display: none;">
138
- <div class="dashboard-error-icon">⚠️</div>
139
- <div class="dashboard-error-message">Failed to load dashboard statistics</div>
140
- <button class="dashboard-retry-btn" data-action="loadDashboardData">Retry</button>
141
- </div>
142
245
 
143
-
144
- <!-- Today's Overview Card -->
145
- <div class="dashboard-card today-overview" id="todayOverviewCard" style="margin-bottom: 24px;">
146
- <div class="dashboard-card-header">
147
- <h3 class="dashboard-card-title">
148
- <span class="dashboard-card-icon">📅</span>
149
- Today's Overview
150
- </h3>
151
- <p class="dashboard-card-subtitle" id="todayDate">Loading...</p>
152
- </div>
153
- <div class="dashboard-stats-grid" id="todayStats">
154
- <div class="dashboard-stat-item tooltip" data-tooltip="Total hours spent reading today">
155
- <span class="dashboard-stat-value" id="todayTotalHours">-</span>
156
- <span class="dashboard-stat-label">Hours Spent</span>
157
- </div>
158
- <div class="dashboard-stat-item tooltip" data-tooltip="Total characters read today">
159
- <span class="dashboard-stat-value" id="todayTotalChars">-</span>
160
- <span class="dashboard-stat-label">Characters</span>
161
- </div>
162
- <div class="dashboard-stat-item tooltip" data-tooltip="Number of reading sessions today">
163
- <span class="dashboard-stat-value" id="todaySessions">-</span>
164
- <span class="dashboard-stat-label">Sessions</span>
165
- </div>
166
- <div class="dashboard-stat-item tooltip" data-tooltip="Average reading speed today">
167
- <span class="dashboard-stat-value" id="todayCharsPerHour">-</span>
168
- <span class="dashboard-stat-label">Chars/Hour</span>
169
- </div>
170
- </div>
171
- </div>
172
-
173
- <!-- Today's Sessions Overview Card -->
174
- <div class="dashboard-card current-session-overview" id="currentSessionOverviewCard" style="margin-bottom: 24px;">
175
- <div class="dashboard-card-header">
176
- <h3 class="dashboard-card-title">
177
- <span class="dashboard-card-icon">🔄</span>
178
- Today's Sessions
179
- </h3>
180
- <p class="dashboard-card-subtitle" id="currentSessionStatus">Loading...</p>
181
- <!-- Two Arrow Keys To Navigate Between Sessions -->
182
- <div class="session-navigation">
183
- <button class="prev-session-btn" data-action="prevSession">←</button>
184
- <button class="next-session-btn" data-action="nextSession">→</button>
185
- <button class="delete-session-btn" data-action="deleteSession" title="Delete Current Session">🗑️</button>
186
- </div>
187
- </div>
188
- <div class="dashboard-stats-grid" id="currentSessionStats">
189
- <div class="dashboard-stat-item tooltip" data-tooltip="Total hours spent reading in latest session">
190
- <span class="dashboard-stat-value" id="currentSessionTotalHours">-</span>
191
- <span class="dashboard-stat-label">Hours Spent</span>
192
- </div>
193
- <div class="dashboard-stat-item tooltip" data-tooltip="Total characters read in latest session">
194
- <span class="dashboard-stat-value" id="currentSessionTotalChars">-</span>
195
- <span class="dashboard-stat-label">Characters</span>
196
- </div>
197
- <div class="dashboard-stat-item tooltip" data-tooltip="Session start time">
198
- <span class="dashboard-stat-value" id="currentSessionStartTime">-</span>
199
- <span class="dashboard-stat-label">Started</span>
200
- </div>
201
- <div class="dashboard-stat-item tooltip" data-tooltip="Session end time">
202
- <span class="dashboard-stat-value" id="currentSessionEndTime">-</span>
203
- <span class="dashboard-stat-label">Ended</span>
204
- </div>
205
- <div class="dashboard-stat-item tooltip" data-tooltip="Average reading speed in latest session">
206
- <span class="dashboard-stat-value" id="currentSessionCharsPerHour">-</span>
207
- <span class="dashboard-stat-label">Chars/Hour</span>
208
- </div>
209
- </div>
210
- </div>
211
-
212
- <div class="chart-container">
213
- <h2>Activity Heatmap</h2>
214
- <div id="heatmapContainer"></div>
215
- </div>
216
246
  <!-- Include shared settings modal -->
217
247
  {% include 'components/settings-modal.html' %}
218
248
  </div>
@@ -32,19 +32,78 @@
32
32
  </div>
33
33
 
34
34
  <div class="search-input-container">
35
- <input
36
- type="text"
37
- id="searchInput"
38
- class="search-input"
35
+ <input
36
+ type="text"
37
+ id="searchInput"
38
+ class="search-input"
39
39
  placeholder="Search for sentences, words, or phrases..."
40
40
  autocomplete="off"
41
41
  />
42
42
  </div>
43
- <div class="regex-checkbox-container" style="margin-top: 8px;">
44
- <label>
45
- <input type="checkbox" id="regexCheckbox" />
46
- Regex search
47
- </label>
43
+ <button id="toggleAdvancedSearch" class="toggle-advanced-btn" style="margin-top: 12px;">
44
+ <span id="toggleIcon">▼</span> Show Advanced Search
45
+ </button>
46
+ <div id="advancedSearchSection" class="regex-options-container" style="display: none; margin-top: 12px; padding: 15px; background: var(--bg-secondary); border-radius: 8px; border: 1px solid var(--border-color);">
47
+ <h4 style="margin: 0 0 10px 0; font-size: 14px; color: var(--text-primary);">Advanced Search Options</h4>
48
+ {% include 'components/regex-input.html' %}
49
+
50
+ <!-- Duplicate Detection Section -->
51
+ <div style="margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--border-color);">
52
+ <button id="toggleDuplicateDetection" class="toggle-advanced-btn" style="margin-bottom: 12px;">
53
+ <span id="duplicateToggleIcon">▼</span> Find Duplicates
54
+ </button>
55
+
56
+ <div id="duplicateDetectionSection" style="display: none; padding: 15px; background: var(--bg-tertiary); border-radius: 6px; border: 1px solid var(--border-color);">
57
+ <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 12px; color: var(--accent-color);">
58
+ <span style="font-size: 18px;">🔄</span>
59
+ <h4 style="margin: 0; font-size: 14px; font-weight: 600;">Duplicate Detection</h4>
60
+ </div>
61
+ <p style="margin: 0 0 15px 0; font-size: 13px; color: var(--text-secondary);">
62
+ Find duplicate sentences within the selected game to improve data quality.
63
+ </p>
64
+
65
+ <div class="form-group" id="duplicateTimeWindowGroup">
66
+ <label class="form-label" style="font-size: 13px; font-weight: 500; color: var(--text-primary); display: block; margin-bottom: 6px;">
67
+ Time Window (minutes):
68
+ </label>
69
+ <input type="number" id="duplicateTimeWindow" class="form-input" min="1" value="5" placeholder="5"
70
+ style="width: 100%; padding: 8px; border: 1px solid var(--border-color); border-radius: 4px; background: var(--bg-primary); color: var(--text-primary);">
71
+ <small style="color: var(--text-tertiary); font-size: 12px; display: block; margin-top: 4px;">
72
+ Only find duplicates that appear within this many minutes of each other.
73
+ </small>
74
+ </div>
75
+
76
+ <div class="form-group" style="margin-top: 12px;">
77
+ <div class="checkbox-container" style="display: flex; align-items: center; gap: 8px;">
78
+ <input type="checkbox" id="duplicateIgnoreTimeWindow" class="checkbox-input"
79
+ style="cursor: pointer; width: 16px; height: 16px;">
80
+ <label for="duplicateIgnoreTimeWindow" class="checkbox-label"
81
+ style="cursor: pointer; font-size: 13px; color: var(--text-primary); margin: 0;">
82
+ Entire Game (ignore time window)
83
+ </label>
84
+ </div>
85
+ <small style="color: var(--text-tertiary); font-size: 12px; display: block; margin-top: 4px; margin-left: 24px;">
86
+ Find ALL duplicates within the selected game regardless of when they occurred.
87
+ </small>
88
+ </div>
89
+
90
+ <div class="form-group" style="margin-top: 12px;">
91
+ <div class="checkbox-container" style="display: flex; align-items: center; gap: 8px;">
92
+ <input type="checkbox" id="duplicateCaseSensitive" class="checkbox-input"
93
+ style="cursor: pointer; width: 16px; height: 16px;">
94
+ <label for="duplicateCaseSensitive" class="checkbox-label"
95
+ style="cursor: pointer; font-size: 13px; color: var(--text-primary); margin: 0;">
96
+ Case sensitive comparison
97
+ </label>
98
+ </div>
99
+ </div>
100
+
101
+ <button id="searchDuplicatesBtn" class="action-btn primary"
102
+ style="margin-top: 15px; width: 100%; padding: 10px; font-weight: 600;">
103
+ 🔍 Search for Duplicates
104
+ </button>
105
+ </div>
106
+ </div>
48
107
  </div>
49
108
  <div class="search-filters">
50
109
  <div class="filter-group">
@@ -60,10 +119,19 @@
60
119
  <option value="date_desc">Newest First</option>
61
120
  <option value="date_asc">Oldest First</option>
62
121
  <option value="game_name">Game Name</option>
122
+ <option value="length_desc">Largest Line</option>
123
+ <option value="length_asc">Smallest Line</option>
63
124
  </select>
64
125
  </div>
65
126
  </div>
66
127
 
128
+ <!-- Date Range Filter -->
129
+ {% set from_id = 'searchFromDate' %}
130
+ {% set to_id = 'searchToDate' %}
131
+ {% set from_tooltip = 'Filter sentences from this date onwards' %}
132
+ {% set to_tooltip = 'Filter sentences up to this date' %}
133
+ {% include 'components/date-range.html' %}
134
+
67
135
  <div class="search-stats">
68
136
  <span id="searchStats">Ready to search</span>
69
137
  <span id="searchTime"></span>
@@ -77,6 +145,7 @@
77
145
  <option value="200">200</option>
78
146
  </select>
79
147
  </div>
148
+ <button id="manualSearchBtn" class="action-btn primary" style="margin-right: 8px;">🔍 Search</button>
80
149
  <button id="selectAllBtn" class="action-btn secondary" style="margin-right: 8px;" disabled>Select All</button>
81
150
  <button id="deleteLinesBtn" class="delete-btn" disabled>Delete Selected</button>
82
151
  </div>