mirror of
https://github.com/discourse/discourse-rewind.git
synced 2025-07-07 22:32:11 +00:00
fixes
This commit is contained in:
parent
3049646b65
commit
6bd637b7b0
@ -6,6 +6,8 @@ module ::DiscourseRewind
|
|||||||
|
|
||||||
def show
|
def show
|
||||||
DiscourseRewind::Rewind::Fetch.call(service_params) do
|
DiscourseRewind::Rewind::Fetch.call(service_params) do
|
||||||
|
on_model_not_found(:year) { raise Discourse::NotFound }
|
||||||
|
on_model_not_found(:user) { raise Discourse::NotFound }
|
||||||
on_success do |reports:|
|
on_success do |reports:|
|
||||||
@reports = reports
|
@reports = reports
|
||||||
render json: MultiJson.dump(reports), status: 200
|
render json: MultiJson.dump(reports), status: 200
|
||||||
|
@ -62,9 +62,11 @@ module DiscourseRewind
|
|||||||
fbffs
|
fbffs
|
||||||
.flatten
|
.flatten
|
||||||
.inject { |h1, h2| h1.merge(h2) { |_, v1, v2| v1 + v2 } }
|
.inject { |h1, h2| h1.merge(h2) { |_, v1, v2| v1 + v2 } }
|
||||||
.sort_by { |_, v| -v }
|
&.sort_by { |_, v| -v }
|
||||||
.first
|
&.first
|
||||||
.first
|
&.first
|
||||||
|
|
||||||
|
return if !fbff_id
|
||||||
|
|
||||||
{
|
{
|
||||||
data: {
|
data: {
|
||||||
|
@ -85,7 +85,7 @@ module DiscourseRewind
|
|||||||
end
|
end
|
||||||
|
|
||||||
def sort_and_limit(reactions)
|
def sort_and_limit(reactions)
|
||||||
reactions.sort_by { |_, v| -v }.first(5).to_h
|
reactions.sort_by { |_, v| v }.first(5).to_h
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -6,12 +6,15 @@ module DiscourseRewind
|
|||||||
class Rewind::Action::ReadingTime < Rewind::Action::BaseReport
|
class Rewind::Action::ReadingTime < Rewind::Action::BaseReport
|
||||||
def call
|
def call
|
||||||
reading_time = UserVisit.where(user_id: user.id).where(visited_at: date).sum(:time_read)
|
reading_time = UserVisit.where(user_id: user.id).where(visited_at: date).sum(:time_read)
|
||||||
|
book = best_book_fit(reading_time)
|
||||||
|
|
||||||
|
return if book.nil?
|
||||||
|
|
||||||
{
|
{
|
||||||
data: {
|
data: {
|
||||||
reading_time: reading_time,
|
reading_time: reading_time,
|
||||||
book: best_book_fit(reading_time)[:title],
|
book: book[:title],
|
||||||
isbn: best_book_fit(reading_time)[:isbn],
|
isbn: book[:isbn],
|
||||||
},
|
},
|
||||||
identifier: "reading-time",
|
identifier: "reading-time",
|
||||||
}
|
}
|
||||||
@ -114,6 +117,8 @@ module DiscourseRewind
|
|||||||
reading_time_rest -= best_fit.last[:reading_time]
|
reading_time_rest -= best_fit.last[:reading_time]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return if books.empty?
|
||||||
|
|
||||||
book_title =
|
book_title =
|
||||||
books.group_by { |book| book }.transform_values(&:count).max_by { |_, count| count }.first
|
books.group_by { |book| book }.transform_values(&:count).max_by { |_, count| count }.first
|
||||||
|
|
||||||
|
@ -20,8 +20,7 @@ module DiscourseRewind
|
|||||||
|
|
||||||
CACHE_DURATION = 5.minutes
|
CACHE_DURATION = 5.minutes
|
||||||
|
|
||||||
YEAR = 2024
|
model :year
|
||||||
|
|
||||||
model :user
|
model :user
|
||||||
model :date
|
model :date
|
||||||
model :reports
|
model :reports
|
||||||
@ -32,12 +31,27 @@ module DiscourseRewind
|
|||||||
User.find_by_username(guardian.user.username)
|
User.find_by_username(guardian.user.username)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_date(params:)
|
def fetch_year
|
||||||
Date.new(YEAR).all_year
|
current_date = Time.zone.now
|
||||||
|
current_month = current_date.month
|
||||||
|
current_year = current_date.year
|
||||||
|
|
||||||
|
case current_month
|
||||||
|
when 1
|
||||||
|
current_year - 1
|
||||||
|
when 12
|
||||||
|
current_year
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_reports(date:, user:, guardian:)
|
def fetch_date(params:, year:)
|
||||||
key = "rewind:#{guardian.user.username}:#{YEAR}"
|
Date.new(year).all_year
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_reports(date:, user:, guardian:, year:)
|
||||||
|
key = "rewind:#{guardian.user.username}:#{year}"
|
||||||
reports = Discourse.redis.get(key)
|
reports = Discourse.redis.get(key)
|
||||||
|
|
||||||
if Rails.env.development? || !reports
|
if Rails.env.development? || !reports
|
||||||
@ -48,7 +62,7 @@ module DiscourseRewind
|
|||||||
.map { |report| report.call(date:, user:, guardian:) }
|
.map { |report| report.call(date:, user:, guardian:) }
|
||||||
Discourse.redis.setex(key, CACHE_DURATION, MultiJson.dump(reports))
|
Discourse.redis.setex(key, CACHE_DURATION, MultiJson.dump(reports))
|
||||||
else
|
else
|
||||||
reports = MultiJson.load(reports, symbolize_keys: true)
|
reports = MultiJson.load(reports.compact, symbolize_keys: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
reports
|
reports
|
||||||
|
@ -13,7 +13,7 @@ const FavoriteTags = <template>
|
|||||||
<div class="rewind-card">
|
<div class="rewind-card">
|
||||||
<a
|
<a
|
||||||
class="favorite-tags__tag"
|
class="favorite-tags__tag"
|
||||||
href={{concat "/tag/-/" data.name}}
|
href={{concat "/tag/" data.name}}
|
||||||
>#{{data.name}}</a>
|
>#{{data.name}}</a>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
const Introduction = <template>
|
const Introduction = <template>
|
||||||
<div class="rewind__introduction">
|
<div class="rewind__introduction">
|
||||||
<img
|
<img
|
||||||
class="rewind-logo-light"
|
class="rewind-logo -light"
|
||||||
src="/plugins/discourse-rewind/images/discourse-rewind-logo.png"
|
src="/plugins/discourse-rewind/images/discourse-rewind-logo.png"
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
class="rewind-logo-dark"
|
class="rewind-logo -dark"
|
||||||
src="/plugins/discourse-rewind/images/discourse-rewind-logo-dark.png"
|
src="/plugins/discourse-rewind/images/discourse-rewind-logo-dark.png"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,6 +37,7 @@ export default class Reactions extends Component {
|
|||||||
"discourse_rewind.reports.post_received_reactions.title"
|
"discourse_rewind.reports.post_received_reactions.title"
|
||||||
}}</h2>
|
}}</h2>
|
||||||
<div class="rewind-report-container">
|
<div class="rewind-report-container">
|
||||||
|
{{log this.receivedReactions}}
|
||||||
{{#each-in this.receivedReactions as |emojiName count|}}
|
{{#each-in this.receivedReactions as |emojiName count|}}
|
||||||
<div class="rewind-card scale">
|
<div class="rewind-card scale">
|
||||||
<span class="rewind-card__emoji">{{replaceEmoji
|
<span class="rewind-card__emoji">{{replaceEmoji
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import { service } from "@ember/service";
|
||||||
|
import DButton from "discourse/components/d-button";
|
||||||
|
import KeyValueStore from "discourse/lib/key-value-store";
|
||||||
|
import icon from "discourse-common/helpers/d-icon";
|
||||||
|
import isRewindActive from "discourse/plugins/discourse-rewind/discourse/lib/is-rewind-active";
|
||||||
|
|
||||||
|
export default class RewindTab extends Component {
|
||||||
|
@service router;
|
||||||
|
|
||||||
|
store = new KeyValueStore("discourse_rewind_" + this.fetchYear);
|
||||||
|
|
||||||
|
get showCallout() {
|
||||||
|
return isRewindActive() && !this.dismissed;
|
||||||
|
}
|
||||||
|
|
||||||
|
get fetchYear() {
|
||||||
|
const currentDate = new Date();
|
||||||
|
const currentMonth = currentDate.getMonth();
|
||||||
|
const currentYear = currentDate.getFullYear();
|
||||||
|
|
||||||
|
if (currentMonth === 0) {
|
||||||
|
return currentYear - 1;
|
||||||
|
} else {
|
||||||
|
return currentYear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get dismissed() {
|
||||||
|
return this.store.getObject("_dismissed") ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
openRewind() {
|
||||||
|
this.store.setObject({ key: "_dismissed", value: true });
|
||||||
|
this.router.transitionTo("/my/activity/rewind");
|
||||||
|
}
|
||||||
|
|
||||||
|
<template>
|
||||||
|
{{#if this.showCallout}}
|
||||||
|
<div class="rewind-callout__container">
|
||||||
|
<DButton
|
||||||
|
@action={{this.openRewind}}
|
||||||
|
class="rewind-callout btn-transparent"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
class="rewind-logo -light"
|
||||||
|
src="/plugins/discourse-rewind/images/discourse-rewind-logo.png"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
class="rewind-logo -dark"
|
||||||
|
src="/plugins/discourse-rewind/images/discourse-rewind-logo-dark.png"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{{icon "arrow-right" class="rewind-callaout__arrow"}}
|
||||||
|
</DButton>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</template>
|
||||||
|
}
|
@ -1,16 +1,19 @@
|
|||||||
import DNavigationItem from "discourse/components/d-navigation-item";
|
import DNavigationItem from "discourse/components/d-navigation-item";
|
||||||
import icon from "discourse-common/helpers/d-icon";
|
import icon from "discourse-common/helpers/d-icon";
|
||||||
import { i18n } from "discourse-i18n";
|
import { i18n } from "discourse-i18n";
|
||||||
|
import isRewindActive from "discourse/plugins/discourse-rewind/discourse/lib/is-rewind-active";
|
||||||
|
|
||||||
const RewindTab = <template>
|
const RewindTab = <template>
|
||||||
<DNavigationItem
|
{{#if isRewindActive}}
|
||||||
@route="userActivity.rewind"
|
<DNavigationItem
|
||||||
@ariaCurrentContext="subNav"
|
@route="userActivity.rewind"
|
||||||
class="user-nav__activity-rewind"
|
@ariaCurrentContext="subNav"
|
||||||
>
|
class="user-nav__activity-rewind"
|
||||||
{{icon "repeat"}}
|
>
|
||||||
<span>{{i18n "discourse_rewind.title"}}</span>
|
{{icon "repeat"}}
|
||||||
</DNavigationItem>
|
<span>{{i18n "discourse_rewind.title"}}</span>
|
||||||
|
</DNavigationItem>
|
||||||
|
{{/if}}
|
||||||
</template>;
|
</template>;
|
||||||
|
|
||||||
export default RewindTab;
|
export default RewindTab;
|
||||||
|
5
assets/javascripts/discourse/lib/is-rewind-active.js
Normal file
5
assets/javascripts/discourse/lib/is-rewind-active.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export default function isRewindActive() {
|
||||||
|
const currentDate = new Date();
|
||||||
|
const currentMonth = currentDate.getMonth();
|
||||||
|
return currentMonth === 0 || currentMonth === 11;
|
||||||
|
}
|
@ -13,3 +13,5 @@
|
|||||||
@import "fonts";
|
@import "fonts";
|
||||||
@import "reading-time";
|
@import "reading-time";
|
||||||
@import "fbff";
|
@import "fbff";
|
||||||
|
@import "rewind-logo";
|
||||||
|
@import "rewind-callout";
|
||||||
|
19
assets/stylesheets/common/rewind-callout.scss
Normal file
19
assets/stylesheets/common/rewind-callout.scss
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
.rewind-callout {
|
||||||
|
background: var(--primary);
|
||||||
|
padding: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: var(--d-border-radius);
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
background: var(--primary-low-mid) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__arrow {
|
||||||
|
color: var(--secondary);
|
||||||
|
}
|
||||||
|
}
|
16
assets/stylesheets/common/rewind-logo.scss
Normal file
16
assets/stylesheets/common/rewind-logo.scss
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
.rewind-logo {
|
||||||
|
height: 50px;
|
||||||
|
|
||||||
|
&.-dark {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
&.-dark {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
&.-light {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -71,26 +71,16 @@
|
|||||||
|
|
||||||
.rewind__introduction {
|
.rewind__introduction {
|
||||||
padding: 1em 0 1em 1em;
|
padding: 1em 0 1em 1em;
|
||||||
background-color: var(--secondary);
|
background-color: var(--primary);
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
box-shadow: 1px 0px 0px 1px var(--primary);
|
box-shadow: 1px 0px 0px 1px var(--primary);
|
||||||
img {
|
|
||||||
height: 50px;
|
.rewind-logo {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
&.rewind-logo-dark {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
&.rewind-logo-dark {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
&.rewind-logo-light {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0 0.5em 0 0;
|
margin: 0 0.5em 0 0;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
31
spec/requests/rewinds_controller_spec.rb
Normal file
31
spec/requests/rewinds_controller_spec.rb
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
RSpec.describe DiscourseRewind::RewindsController do
|
||||||
|
before { SiteSetting.discourse_rewind_enabled = true }
|
||||||
|
|
||||||
|
describe "#show" do
|
||||||
|
fab!(:current_user) { Fabricate(:user) }
|
||||||
|
|
||||||
|
before { sign_in(current_user) }
|
||||||
|
|
||||||
|
context "when out of valid month" do
|
||||||
|
before { freeze_time DateTime.parse("2022-11-24") }
|
||||||
|
|
||||||
|
it "returns 404" do
|
||||||
|
get "/rewinds.json"
|
||||||
|
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when in valid month" do
|
||||||
|
before { freeze_time DateTime.parse("2022-12-24") }
|
||||||
|
|
||||||
|
it "returns 200" do
|
||||||
|
get "/rewinds.json"
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
40
spec/system/rewind_tab_spec.rb
Normal file
40
spec/system/rewind_tab_spec.rb
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
describe "DiscourseRewind | rewind tab", type: :system do
|
||||||
|
fab!(:current_user) { Fabricate(:user) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
SiteSetting.discourse_rewind_enabled = true
|
||||||
|
sign_in(current_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when in january" do
|
||||||
|
before { freeze_time DateTime.parse("2022-01-10") }
|
||||||
|
|
||||||
|
it "shows the tab" do
|
||||||
|
visit("/my/activity")
|
||||||
|
|
||||||
|
expect(page).to have_selector(".user-nav__activity-rewind")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when in december" do
|
||||||
|
before { freeze_time DateTime.parse("2022-12-05") }
|
||||||
|
|
||||||
|
it "shows the tab" do
|
||||||
|
visit("/my/activity")
|
||||||
|
|
||||||
|
expect(page).to have_selector(".user-nav__activity-rewind")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when in november" do
|
||||||
|
before { freeze_time DateTime.parse("2022-11-24") }
|
||||||
|
|
||||||
|
it "doesn show the tab" do
|
||||||
|
visit("/my/activity")
|
||||||
|
|
||||||
|
expect(page).to have_no_selector(".user-nav__activity-rewind")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user