diff -r 586dcd606e47 -r 3d2720f95cfb src/html.cpp
--- a/src/html.cpp Sat Jun 28 11:32:08 2025 +0200
+++ b/src/html.cpp Tue Jul 15 19:14:29 2025 +0200
@@ -187,13 +187,33 @@
const summaries = JSON.parse(this.dataset.summaries);
// Create popup content
- let content = `×
-
${date}: ${summaries.length} commit${summaries.length !== '1' ? 's' : ''}
`;
- content += '';
- summaries.forEach(summary => {
- content += `- ${summary}
`;
- });
- content += '
';
+ let content = '×';
+ if (Array.isArray(summaries)) {
+ content += `${date}: ${summaries.length} commit${summaries.length !== 1 ? 's' : ''}
`;
+ content += '';
+ summaries.forEach(summary => {
+ content += `- ${summary}
`;
+ });
+ content += '
';
+ } else {
+ const repos = Object.keys(summaries).sort();
+ let total_commits = 0;
+ for (const repo of repos) total_commits += summaries[repo].length;
+ content += `${date}: ${total_commits} commit${total_commits !== 1 ? 's' : ''}
`;
+ for (const repo of repos) {
+ const commits = summaries[repo];
+ if (repos.length > 1) {
+ content += `${repo} (${commits.length} commit${commits.length !== 1 ? 's' : ''})
`;
+ } else {
+ content += `${repo}
`;
+ }
+ content += '';
+ commits.forEach(commit => {
+ content += `- ${commit}
`;
+ });
+ content += '
';
+ }
+ }
popup.innerHTML = content;
// Position popup near the cell
@@ -326,7 +346,7 @@
puts(" | ");
}
-void html::cell(year_month_day ymd, const fm::commits &commits) {
+void html::cell(year_month_day ymd, bool hide_repo_names, const fm::commits &commits) {
const char *color_class;
if (commits.count() == 0) {
color_class = "zero-commits";
@@ -351,25 +371,41 @@
static_cast(ymd.month()),
static_cast(ymd.day()));
- // Build a JSON array of commit summaries
- // We have to iterate in reverse order to sort the summaries chronologically
- std::string summaries_json = "[";
- for (const auto &summary : commits.summaries | std::views::reverse) {
- // Escape quotes in JSON
- size_t pos = summary.find('\"');
- if (pos == std::string::npos) {
- summaries_json += "\"" + summary + "\",";
- } else {
- std::string escaped = summary;
- do {
- escaped.replace(pos, 1, "\\\"");
- pos += 2;
- } while ((pos = escaped.find('\"', pos)) != std::string::npos);
- summaries_json += "\"" + escaped + "\",";
+ // Build a JSON object of commit summaries
+ auto escape_json = [](std::string str) static {
+ size_t pos = str.find('\"');
+ if (pos == std::string::npos) return str;
+ std::string escaped = std::move(str);
+ do {
+ escaped.replace(pos, 1, "\\\"");
+ pos += 2;
+ } while ((pos = escaped.find('\"', pos)) != std::string::npos);
+ return escaped;
+ };
+ auto add_summaries = [escape_json](std::string &json, const std::vector &summaries) {
+ // We have to iterate in reverse order to sort the summaries chronologically
+ for (const auto &summary : summaries | std::views::reverse) {
+ json += "\"" + escape_json(summary) + "\",";
}
+ json.pop_back();
+ };
+ std::string summaries_json;
+ if (hide_repo_names) {
+ summaries_json += '[';
+ for (const auto &summaries: commits.summaries | std::views::values) {
+ add_summaries(summaries_json, summaries);
+ }
+ summaries_json += ']';
+ } else {
+ summaries_json += '{';
+ for (const auto &[repo, summaries] : commits.summaries) {
+ summaries_json += "\"" + escape_json(repo) + "\":[";
+ add_summaries(summaries_json, summaries);
+ summaries_json += "],";
+ }
+ summaries_json.pop_back();
+ summaries_json += '}';
}
- summaries_json.pop_back();
- summaries_json += "]";
indent();
printf(" | \n",