From 3af6a12a55c0ace81b5140856397d1a7a70bc64f Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Fri, 20 Dec 2024 18:56:02 +0100 Subject: [PATCH] start implementing reports --- .../rewind/action/reactions.rb | 1 + .../components/reports/activity-calendar.gjs | 61 ++++++++++ .../components/reports/best-posts.gjs | 9 ++ .../components/reports/best-topics.gjs | 9 ++ .../reports/favorite-categories.gjs | 9 ++ .../components/reports/favorite-tags.gjs | 9 ++ .../discourse/components/reports/fbff.gjs | 13 +++ .../components/reports/reactions.gjs | 55 ++++++++- .../components/reports/reading-time.gjs | 13 +++ .../components/reports/word-cloud.gjs | 9 ++ .../discourse/components/rewind.gjs | 105 +++++++++++++++--- .../stylesheets/common/activity-calendar.scss | 25 +++++ assets/stylesheets/common/card.scss | 9 ++ assets/stylesheets/common/index.scss | 3 + .../common/post-received-reactions.scss | 16 +++ .../common/post-used-reactions.scss | 20 ++++ assets/stylesheets/common/report.scss | 2 - assets/stylesheets/common/rewind.scss | 78 ++++++++++--- assets/stylesheets/mobile/report.scss | 2 - assets/stylesheets/mobile/rewind.scss | 12 +- 20 files changed, 418 insertions(+), 42 deletions(-) create mode 100644 assets/javascripts/discourse/components/reports/activity-calendar.gjs create mode 100644 assets/javascripts/discourse/components/reports/best-posts.gjs create mode 100644 assets/javascripts/discourse/components/reports/best-topics.gjs create mode 100644 assets/javascripts/discourse/components/reports/favorite-categories.gjs create mode 100644 assets/javascripts/discourse/components/reports/favorite-tags.gjs create mode 100644 assets/javascripts/discourse/components/reports/fbff.gjs create mode 100644 assets/javascripts/discourse/components/reports/reading-time.gjs create mode 100644 assets/javascripts/discourse/components/reports/word-cloud.gjs create mode 100644 assets/stylesheets/common/activity-calendar.scss create mode 100644 assets/stylesheets/common/post-received-reactions.scss create mode 100644 assets/stylesheets/common/post-used-reactions.scss diff --git a/app/services/discourse_rewind/rewind/action/reactions.rb b/app/services/discourse_rewind/rewind/action/reactions.rb index 1bd03b2..e154661 100644 --- a/app/services/discourse_rewind/rewind/action/reactions.rb +++ b/app/services/discourse_rewind/rewind/action/reactions.rb @@ -24,6 +24,7 @@ module DiscourseRewind .where(posts: { user_id: user.id }) .where(created_at: date) .group(:reaction_value) + .limit(5) .count end diff --git a/assets/javascripts/discourse/components/reports/activity-calendar.gjs b/assets/javascripts/discourse/components/reports/activity-calendar.gjs new file mode 100644 index 0000000..419afab --- /dev/null +++ b/assets/javascripts/discourse/components/reports/activity-calendar.gjs @@ -0,0 +1,61 @@ +import Component from "@glimmer/component"; +import { action } from "@ember/object"; +import concatClass from "discourse/helpers/concat-class"; + +const ROWS = 7; +const COLS = 53; + +export default class ActivityCalendar extends Component { + get rowsArray() { + const data = this.args.report.data; + let rowsArray = []; + + for (let r = 0; r < ROWS; r++) { + let rowData = []; + for (let c = 0; c < COLS; c++) { + const index = c * ROWS + r; + rowData.push(data[index] ? data[index] : ""); + } + rowsArray.push(rowData); + } + + return rowsArray; + } + + @action + computeClass(count) { + if (!count) { + return "-empty"; + } else if (count < 10) { + return "-low"; + } else if (count < 20) { + return "-medium"; + } else { + return "-high"; + } + } + + +} diff --git a/assets/javascripts/discourse/components/reports/best-posts.gjs b/assets/javascripts/discourse/components/reports/best-posts.gjs new file mode 100644 index 0000000..3112e8c --- /dev/null +++ b/assets/javascripts/discourse/components/reports/best-posts.gjs @@ -0,0 +1,9 @@ +import Component from "@glimmer/component"; + +export default class BestPosts extends Component { + +} diff --git a/assets/javascripts/discourse/components/reports/best-topics.gjs b/assets/javascripts/discourse/components/reports/best-topics.gjs new file mode 100644 index 0000000..7faf2ab --- /dev/null +++ b/assets/javascripts/discourse/components/reports/best-topics.gjs @@ -0,0 +1,9 @@ +import Component from "@glimmer/component"; + +export default class BestTopics extends Component { + +} diff --git a/assets/javascripts/discourse/components/reports/favorite-categories.gjs b/assets/javascripts/discourse/components/reports/favorite-categories.gjs new file mode 100644 index 0000000..5d99af0 --- /dev/null +++ b/assets/javascripts/discourse/components/reports/favorite-categories.gjs @@ -0,0 +1,9 @@ +import Component from "@glimmer/component"; + +export default class FavoriteCategories extends Component { + +} diff --git a/assets/javascripts/discourse/components/reports/favorite-tags.gjs b/assets/javascripts/discourse/components/reports/favorite-tags.gjs new file mode 100644 index 0000000..26c1d4f --- /dev/null +++ b/assets/javascripts/discourse/components/reports/favorite-tags.gjs @@ -0,0 +1,9 @@ +import Component from "@glimmer/component"; + +export default class FavoriteTags extends Component { + +} diff --git a/assets/javascripts/discourse/components/reports/fbff.gjs b/assets/javascripts/discourse/components/reports/fbff.gjs new file mode 100644 index 0000000..5d5882d --- /dev/null +++ b/assets/javascripts/discourse/components/reports/fbff.gjs @@ -0,0 +1,13 @@ +import Component from "@glimmer/component"; + +export default class FBFF extends Component { + +} diff --git a/assets/javascripts/discourse/components/reports/reactions.gjs b/assets/javascripts/discourse/components/reports/reactions.gjs index ad023be..ae66352 100644 --- a/assets/javascripts/discourse/components/reports/reactions.gjs +++ b/assets/javascripts/discourse/components/reports/reactions.gjs @@ -1,13 +1,60 @@ import Component from "@glimmer/component"; +import { concat } from "@ember/helper"; +import { action } from "@ember/object"; +import { htmlSafe } from "@ember/template"; +import replaceEmoji from "discourse/helpers/replace-emoji"; export default class Reactions extends Component { + @action + cleanEmoji(emojiName) { + return emojiName.replaceAll(/_/g, " "); + } + + get totalPostUsedReactions() { + return Object.values( + this.args.report.data.post_used_reactions ?? {} + ).reduce((acc, count) => acc + count, 0); + } + + @action + computePercentage(count) { + return `${((count / this.totalPostUsedReactions) * 100).toFixed(2)}%`; + } + + @action + computePercentageStyle(count) { + return htmlSafe(`width: ${this.computePercentage(count)}`); + } + } diff --git a/assets/javascripts/discourse/components/reports/reading-time.gjs b/assets/javascripts/discourse/components/reports/reading-time.gjs new file mode 100644 index 0000000..c16be52 --- /dev/null +++ b/assets/javascripts/discourse/components/reports/reading-time.gjs @@ -0,0 +1,13 @@ +import Component from "@glimmer/component"; + +export default class ReadingTime extends Component { + +} diff --git a/assets/javascripts/discourse/components/reports/word-cloud.gjs b/assets/javascripts/discourse/components/reports/word-cloud.gjs new file mode 100644 index 0000000..fde9398 --- /dev/null +++ b/assets/javascripts/discourse/components/reports/word-cloud.gjs @@ -0,0 +1,9 @@ +import Component from "@glimmer/component"; + +export default class WordCloud extends Component { + +} diff --git a/assets/javascripts/discourse/components/rewind.gjs b/assets/javascripts/discourse/components/rewind.gjs index 9aa0fff..665b7d8 100644 --- a/assets/javascripts/discourse/components/rewind.gjs +++ b/assets/javascripts/discourse/components/rewind.gjs @@ -1,25 +1,44 @@ import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; +import { on } from "@ember/modifier"; import { action } from "@ember/object"; import didInsert from "@ember/render-modifiers/modifiers/did-insert"; +import { schedule } from "@ember/runloop"; import { eq } from "truth-helpers"; import DButton from "discourse/components/d-button"; import concatClass from "discourse/helpers/concat-class"; import { ajax } from "discourse/lib/ajax"; import { popupAjaxError } from "discourse/lib/ajax-error"; +import ActivityCalendar from "discourse/plugins/discourse-rewind/discourse/components/reports/activity-calendar"; +import BestPosts from "discourse/plugins/discourse-rewind/discourse/components/reports/best-posts"; +import BestTopics from "discourse/plugins/discourse-rewind/discourse/components/reports/best-topics"; +import FavoriteCategories from "discourse/plugins/discourse-rewind/discourse/components/reports/favorite-categories"; +import FavoriteTags from "discourse/plugins/discourse-rewind/discourse/components/reports/favorite-tags"; +import FBFF from "discourse/plugins/discourse-rewind/discourse/components/reports/fbff"; import Reactions from "discourse/plugins/discourse-rewind/discourse/components/reports/reactions"; +import ReadingTime from "discourse/plugins/discourse-rewind/discourse/components/reports/reading-time"; +import WordCloud from "discourse/plugins/discourse-rewind/discourse/components/reports/word-cloud"; export default class Rewind extends Component { @tracked rewind = []; @tracked fullScreen = true; + @tracked loadingRewind = false; + + @action + registerScrollWrapper(element) { + this.scrollWrapper = element; + } @action async loadRewind() { try { + this.loadingRewind = true; this.rewind = await ajax("/rewinds"); } catch (e) { popupAjaxError(e); + } finally { + this.loadingRewind = false; } } @@ -28,30 +47,86 @@ export default class Rewind extends Component { this.fullScreen = !this.fullScreen; } - reportComponentForIdentifier(identifier) { - if (identifier === "reactions") { - return Reactions; + @action + handleEscape(event) { + if (this.fullScreen && event.key === "Escape") { + this.fullScreen = false; } } } diff --git a/assets/stylesheets/common/activity-calendar.scss b/assets/stylesheets/common/activity-calendar.scss new file mode 100644 index 0000000..3045f7c --- /dev/null +++ b/assets/stylesheets/common/activity-calendar.scss @@ -0,0 +1,25 @@ +.rewind-report-page.-activity-calendar { + .rewind-calendar { + tr { + border: none; + } + } + + .rewind-calendar-cell { + height: 10px; + width: 10px; + + &.-empty { + background: var(--tertiary-very-low); + } + &.-low { + background: var(--tertiary-low); + } + &.-medium { + background: var(--tertiary-medium); + } + &.-high { + background: var(--tertiary-hig); + } + } +} diff --git a/assets/stylesheets/common/card.scss b/assets/stylesheets/common/card.scss index 3a9d0d9..6751925 100644 --- a/assets/stylesheets/common/card.scss +++ b/assets/stylesheets/common/card.scss @@ -1,2 +1,11 @@ .rewind-card { + box-shadow: 0 0 0 1px var(--primary-300), 0 0 0 4px var(--primary-100); + border-radius: calc(var(--d-border-radius) / 2); + display: flex; + flex-direction: column; + text-align: center; + padding: 1em; + box-sizing: border-box; + align-items: center; + justify-content: center; } diff --git a/assets/stylesheets/common/index.scss b/assets/stylesheets/common/index.scss index 9cf8794..6560dd3 100644 --- a/assets/stylesheets/common/index.scss +++ b/assets/stylesheets/common/index.scss @@ -1,3 +1,6 @@ @import "rewind"; @import "report"; @import "card"; +@import "post-received-reactions"; +@import "post-used-reactions"; +@import "activity-calendar"; diff --git a/assets/stylesheets/common/post-received-reactions.scss b/assets/stylesheets/common/post-received-reactions.scss new file mode 100644 index 0000000..bf6b60f --- /dev/null +++ b/assets/stylesheets/common/post-received-reactions.scss @@ -0,0 +1,16 @@ +.rewind-report-page.-post-received-reactions { + .rewind-reactions-chart { + display: flex; + gap: 1em; + } + + .rewind-card { + width: 177px; + height: 190px; + + .emoji { + width: 72px; + height: 72px; + } + } +} diff --git a/assets/stylesheets/common/post-used-reactions.scss b/assets/stylesheets/common/post-used-reactions.scss new file mode 100644 index 0000000..354c1c4 --- /dev/null +++ b/assets/stylesheets/common/post-used-reactions.scss @@ -0,0 +1,20 @@ +.rewind-report-page.-post-used-reactions { + display: flex; + gap: 1em; + + .rewind-reactions-chart { + display: flex; + flex-direction: column; + gap: 1em; + } + + .rewind-reactions-row { + display: flex; + gap: 1em; + } + + .rewind-reactions-bar { + background: var(--tertiary); + height: 50px; + } +} diff --git a/assets/stylesheets/common/report.scss b/assets/stylesheets/common/report.scss index 9a4fd59..38f1ffd 100644 --- a/assets/stylesheets/common/report.scss +++ b/assets/stylesheets/common/report.scss @@ -9,6 +9,4 @@ box-sizing: border-box; font-weight: 700; font-size: var(--font-up-2); - height: 100cqh; - width: 100cqw; } diff --git a/assets/stylesheets/common/rewind.scss b/assets/stylesheets/common/rewind.scss index 0cef51c..28f7dca 100644 --- a/assets/stylesheets/common/rewind.scss +++ b/assets/stylesheets/common/rewind.scss @@ -1,14 +1,11 @@ -.rewind { - width: 280px; - height: 400px; - background-color: var(--secondary); +.rewind-container { border-radius: var(--d-border-radius); - overflow-y: auto; - overflow-x: hidden; - border: 1px solid var(--primary-very-low); box-sizing: border-box; position: relative; - container-type: size; + display: flex; + align-items: center; + justify-content: center; + padding: 2em 4em; &.-fullscreen { top: 0; @@ -16,14 +13,69 @@ right: 0; bottom: 0; z-index: 9999; - width: 100vw; + width: calc(100vw - (100vw - 100%) + 2px); height: 100vh; position: fixed; + background: rgba(255, 255, 255, 0.5); + border-radius: 16px; + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1); + backdrop-filter: blur(4.9px); + -webkit-backdrop-filter: blur(4.9px); } } -.rewind__exit-fullscreen-btn { - position: sticky; - top: 5px; - left: calc(100% - 45px); +.rewind { + width: 100vw; + height: 100vh; + max-height: 100%; + max-width: 100%; + background-color: var(--secondary); + box-shadow: 0 0 0 1px var(--primary-300), 0 0 0 4px var(--primary-100); + border-radius: calc(var(--d-border-radius) / 2); + container-type: size; + position: relative; +} + +.rewind__scroll-wrapper { + overflow-y: auto; + overflow-x: hidden; + height: 100%; + width: 100%; + position: relative; +} + +.rewind__exit-fullscreen-btn { + position: absolute; + top: 5px; + right: 20px; + z-index: 1; +} + +.rewind__prev-btn { + position: absolute; + bottom: 5px; + left: 5px; + z-index: 1; +} + +.rewind__next-btn { + position: absolute; + bottom: 5px; + right: 5px; + z-index: 1; +} + +.rewind-loader { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100cqh; + gap: 1em; + box-sizing: border-box; + + &__text { + font-weight: 700; + font-size: var(--font-up-2); + } } diff --git a/assets/stylesheets/mobile/report.scss b/assets/stylesheets/mobile/report.scss index 8c813f8..d6646f0 100644 --- a/assets/stylesheets/mobile/report.scss +++ b/assets/stylesheets/mobile/report.scss @@ -1,4 +1,2 @@ .report-page { - width: 100vw; - height: 100vh; } diff --git a/assets/stylesheets/mobile/rewind.scss b/assets/stylesheets/mobile/rewind.scss index 65efbd9..f905afa 100644 --- a/assets/stylesheets/mobile/rewind.scss +++ b/assets/stylesheets/mobile/rewind.scss @@ -1,7 +1,7 @@ -.rewind { - background-color: var(--secondary); - border-radius: var(--d-border-radius); - overflow-y: auto; - overflow-x: hidden; - border: 1px solid var(--primary-very-low); +.rewind-container { + padding: 1em; + box-sizing: border-box; +} + +.rewind { }