Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEV: Adds age support to discourse-cakeday plugin #77

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions assets/javascripts/discourse/components/user-age-title.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Component from "@ember/component";
import computed from "discourse-common/utils/decorators";
import I18n from "I18n";

export default Component.extend({
classNames: ["user-age-title"],

@computed("title")
titleText(title) {
return I18n.t('js.user.date_of_birth.label') + ': ' + title;
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
cakedayBirthday,
cakedayBirthdayTitle,
cakedayTitle,
userAgeTitle,
userBirthdateTitle,
} from "discourse/plugins/discourse-cakeday/discourse/lib/cakeday";

export default {
Expand All @@ -17,5 +19,11 @@ export default {
"cakedayBirthdayTitle",
cakedayBirthdayTitle(args.user, this.currentUser)
);
const isStaff = this.currentUser && this.currentUser.staff;
const isAdmin = this.currentUser && this.currentUser.admin;
if (isAdmin || isStaff) {
component.set("userAgeTitle", userAgeTitle(args.user));
component.set("userBirthdateTitle", userBirthdateTitle(args.user));
}
},
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
export default {
setupComponent(args, component) {
const year = 1904;
const months = moment.months().map((month, index) => {
return { name: month, value: index + 1 };
});

const days = Array.from(Array(31).keys()).map((x) => (x + 1).toString());

const dateOfBirth = args.model.get("date_of_birth");
const userBirthdayYear = dateOfBirth
? (moment(dateOfBirth, "YYYY-MM-DD").year() !== year ? moment(dateOfBirth, "YYYY-MM-DD").year() : null)
: null;
const userBirthdayMonth = dateOfBirth
? moment(dateOfBirth, "YYYY-MM-DD").month() + 1
: null;
Expand All @@ -15,22 +19,28 @@ export default {
: null;

component.setProperties({
year,
months,
days,
userBirthdayYear,
userBirthdayMonth,
userBirthdayDay,
});

const updateBirthday = function () {
let date = "";

if (component.userBirthdayMonth && component.userBirthdayDay) {
if (component.userBirthdayYear && component.userBirthdayMonth && component.userBirthdayDay) {
date = `${component.userBirthdayYear}-${component.userBirthdayMonth}-${component.userBirthdayDay}`;
}
else if (component.userBirthdayMonth && component.userBirthdayDay) {
date = `1904-${component.userBirthdayMonth}-${component.userBirthdayDay}`;
}

args.model.set("date_of_birth", date);
};

component.addObserver("userBirthdayYear", updateBirthday);
component.addObserver("userBirthdayMonth", updateBirthday);
component.addObserver("userBirthdayDay", updateBirthday);
},
Expand Down
15 changes: 13 additions & 2 deletions assets/javascripts/discourse/initializers/cakeday.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,20 @@ function initializeCakeday(api) {
});
},

@observes("userBirthdayMonth", "userBirthdayDay")
@observes("userBirthdayYear", "userBirthdayMonth", "userBirthdayDay")
_setUserDateOfBirth() {
const userBirthdayYear = this.get("userBirthdayYear");
const userBirthdayMonth = this.get("userBirthdayMonth");
const userBirthdayDay = this.get("userBirthdayDay");
const user = this.get("model");
let date = "";

if (userBirthdayMonth !== "" && userBirthdayDay !== "") {
if (userBirthdayYear !== "" && userBirthdayMonth !== "" && userBirthdayDay !== "") {
date = `${this.get("userBirthdayYear")}-${this.get("userBirthdayMonth")}-${this.get(
"userBirthdayDay"
)}`;
}
else if (userBirthdayMonth !== "" && userBirthdayDay !== "") {
date = `1904-${this.get("userBirthdayMonth")}-${this.get(
"userBirthdayDay"
)}`;
Expand All @@ -46,6 +52,11 @@ function initializeCakeday(api) {
user.set("date_of_birth", date);
},

@discourseComputed("model.date_of_birth")
userBirthdayYear(dateOfBirth) {
return moment(dateOfBirth, "YYYY-MM-DD").year() + 1;
},

@discourseComputed("model.date_of_birth")
userBirthdayMonth(dateOfBirth) {
return moment(dateOfBirth, "YYYY-MM-DD").month() + 1;
Expand Down
13 changes: 13 additions & 0 deletions assets/javascripts/discourse/lib/cakeday.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isEmpty } from "@ember/utils";
import I18n from "I18n";

export function isSameDay(date, opts) {
let formatString = "YYYY";
Expand Down Expand Up @@ -30,6 +31,18 @@ export function cakedayBirthday(dateOfBirth) {
return isSameDay(dateOfBirth);
}

export function userAge(dateOfBirth) {
return dateOfBirth ? (moment(dateOfBirth, "YYYY-MM-DD").year() !== 1904 ? moment().diff(dateOfBirth, 'years') : null) : null;
}

export function userAgeTitle(user) {
return (user.date_of_birth && moment(user.date_of_birth, "YYYY-MM-DD").year() !== 1904) ? userAge(user.date_of_birth) + ' ' + I18n.default.t("relative_time_picker.years", {count: userAge(user.date_of_birth)}) : null;
}

export function userBirthdateTitle(user) {
return (user.date_of_birth && moment(user.date_of_birth, "YYYY-MM-DD").year() !== 1904) ? moment(user.date_of_birth).format(I18n.t("dates.long_with_year_no_time")) : null;
}

export function cakedayTitle(user, currentUser) {
if (isSameUser(user, currentUser)) {
return "user.anniversary.user_title";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div title={{titleText}}>
{{userage}}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
{{emoji-images list=siteSettings.cakeday_emoji title=cakedayTitle}}
{{/if}}
{{/if}}
{{user-age-title userage=userAgeTitle title=userBirthdateTitle}}
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,76 @@
<div class="control-group">
<label class="control-label">{{i18n "user.date_of_birth.label"}}</label>
<div class="controls">
{{combo-box
content=months
value=userBirthdayMonth
valueAttribute="value"
valueProperty="value"
none="cakeday.none"
options=(hash
clearable=true
autoInsertNoneItem=false
)
onChange=(action (mut userBirthdayMonth))
}}

{{combo-box
content=days
value=userBirthdayDay
valueProperty=null
nameProperty=null
none="cakeday.none"
options=(hash
clearable=true
autoInsertNoneItem=false
)
onChange=(action (mut userBirthdayDay))
}}
{{#if siteSettings.cakeday_birthday_formatdmy}}
{{combo-box
content=days
value=userBirthdayDay
valueProperty=null
nameProperty=null
none="cakeday.dd"
options=(hash
clearable=true
autoInsertNoneItem=false
)
onChange=(action (mut userBirthdayDay))
}}
{{#if siteSettings.cakeday_birthday_show_year}}
-
{{/if}}
{{combo-box
content=months
value=userBirthdayMonth
valueAttribute="value"
valueProperty="value"
none="cakeday.mm"
options=(hash
clearable=true
autoInsertNoneItem=false
)
onChange=(action (mut userBirthdayMonth))
}}
{{else}}
{{combo-box
content=months
value=userBirthdayMonth
valueAttribute="value"
valueProperty="value"
none="cakeday.mm"
options=(hash
clearable=true
autoInsertNoneItem=false
)
onChange=(action (mut userBirthdayMonth))
}}
{{#if siteSettings.cakeday_birthday_show_year}}
-
{{/if}}
{{combo-box
content=days
value=userBirthdayDay
valueProperty=null
nameProperty=null
none="cakeday.dd"
options=(hash
clearable=true
autoInsertNoneItem=false
)
onChange=(action (mut userBirthdayDay))
}}
{{/if}}
{{#if siteSettings.cakeday_birthday_show_year}}
-
{{input
type="number"
class="year"
content=year
value=userBirthdayYear
min=1905
max=2904
placeholder=(i18n "cakeday.yyyy")
onChange=(action (mut userBirthdayYear))
}}
{{/if}}
</div>
</div>
{{/if}}
5 changes: 5 additions & 0 deletions assets/stylesheets/mobile/user-date-of-birth-input.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
.mobile-view .user-custom-preferences-outlet.user-date-of-birth-input {
input.year {
width: 62px;
}
}
.user-custom-preferences-outlet.user-date-of-birth-input {
select {
width: 49%;
Expand Down
7 changes: 7 additions & 0 deletions assets/stylesheets/user-date-of-birth-input.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.user-custom-preferences-outlet.user-date-of-birth-input {
input.year {
width: 80px;
vertical-align: middle;
height: 41.5px;
}
}
4 changes: 4 additions & 0 deletions config/locales/client.da.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ da:
user_title: "I dag er det din fødselsdag!"
title: "I dag er det min fødselsdag!"
label: "Fødselsdato"
show_age: "Vis alder til brugere"
anniversary:
user_title: "I dag er årsdagen hvor du blev en del af vores fælleskab!"
title: "I dag er årsdagen for at jeg blev en del af dette fælleskab!"
cakeday:
dd: "DD"
mm: "MM"
yyyy: "ÅÅÅÅ"
title: Kagedag
today: "I dag"
tomorrow: "I morgen"
Expand Down
3 changes: 3 additions & 0 deletions config/locales/client.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ en:
title: "Today is the anniversary of the day I joined this community!"
cakeday:
none: " "
dd: "DD"
mm: "MM"
yyyy: "YYYY"
title: Cakeday
today: "Today"
tomorrow: "Tomorrow"
Expand Down
2 changes: 2 additions & 0 deletions config/locales/server.da.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
da:
site_settings:
cakeday_enabled: "Vis cakeday humørikon[er] ved siden af navnet på brugeren, på den dato, hvor de blev medlem af Discourse."
cakeday_birthday_show_year: "Vis Kagedag års vælger, for at tillade brugere at indtaste deres alder."
cakeday_birthday_formatdmy: "Vis Kagedag vælgere som DD-MM-ÅÅÅÅ, i stedet for MM-DD-ÅÅÅÅ"
cakeday_emoji: "De humørikon[er], der vises ved siden af navnet på brugeren, på den dato, hvor de blev medlem af Discourse. Flere humørikoner kan specificeres ved: smile|cake|smile"
cakeday_birthday_enabled: "Vis fødselsdags humørikon[er] ved siden af navnet på brugeren, på deres fødselsdag."
cakeday_birthday_emoji: "De humørikon[er], der vises ved siden af navnet på brugeren, på deres fødselsdag. Flere humørikoner kan specificeres ved: smile|cake|smile"
2 changes: 2 additions & 0 deletions config/locales/server.en.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
en:
site_settings:
cakeday_enabled: "Show cakeday emoji[s] beside the user's name on the date they joined Discourse."
cakeday_birthday_show_year: "Show cakeday year selector, to allow users to input their age."
cakeday_birthday_formatdmy: "Show cakeday selectors as DD-MM-YYYY, instead of MM-DD-YYYY"
cakeday_emoji: "The emoji[s] that will be shown beside the user's name on the date that they joined Discourse. Multiple emojis can be specified by: smile|cake|smile"
cakeday_birthday_enabled: "Show birthday emoji[s] beside the user's name on their birthday."
cakeday_birthday_emoji: "The emoji[s] that will be shown beside the user's name on their birthday. Multiple emojis can be specified by: smile|cake|smile"
6 changes: 6 additions & 0 deletions config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@ plugins:
cakeday_birthday_emoji:
default: 'birthday'
client: true
cakeday_birthday_show_year:
default: false
client: true
cakeday_birthday_formatdmy:
default: false
client: true
11 changes: 10 additions & 1 deletion plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

register_asset 'stylesheets/cakeday.scss'
register_asset 'stylesheets/emoji-images.scss'
register_asset 'stylesheets/user-date-of-birth-input.scss'
register_asset 'stylesheets/mobile/user-date-of-birth-input.scss'

register_svg_icon "birthday-cake" if respond_to?(:register_svg_icon)
Expand Down Expand Up @@ -60,7 +61,15 @@ class ::User
end

add_to_serializer(:user_card, :date_of_birth, false) do
object.date_of_birth
if object.date_of_birth != nil
if (scope.is_staff? || scope.is_admin?)
object.date_of_birth
else
Date.new(1904, object.date_of_birth.month, object.date_of_birth.day)
end
else
nil
end
end

add_to_serializer(:user_card, :include_date_of_birth?) do
Expand Down
16 changes: 16 additions & 0 deletions spec/serializers/user_serializer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,26 @@

RSpec.describe UserSerializer do
let(:user) { Fabricate(:user, date_of_birth: '2017-04-05') }
let!(:admin) { Fabricate(:admin) }
let(:agesafe_date_of_birth) { '1904-04-05' }

context 'when user is logged in' do
let(:serializer) { described_class.new(user, scope: Guardian.new(user), root: false) }

it "should include the user's date of birth" do
expect(serializer.as_json[:date_of_birth]).to eq(agesafe_date_of_birth)
end

it "should not include the user's date of birth when cakeday_birthday_enabled is false" do
SiteSetting.cakeday_birthday_enabled = false

expect(serializer.as_json[:date_of_birth]).to eq(nil)
end
end

context 'when admin is logged in' do
let(:serializer) { described_class.new(user, scope: Guardian.new(admin), root: false) }

it "should include the user's date of birth" do
expect(serializer.as_json[:date_of_birth]).to eq(user.date_of_birth)
end
Expand Down