Change to split birthday into year, month, and day
This commit is contained in:
parent
fa82ec15d5
commit
5ebd24c801
|
@ -21,7 +21,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
|
|||
private
|
||||
|
||||
def account_params
|
||||
params.permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, :searchability, :birthday, :location, fields_attributes: [:name, :value])
|
||||
params.permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, :searchability, :birthday, :birth_year, :birth_month, :birth_day, :location, fields_attributes: [:name, :value])
|
||||
end
|
||||
|
||||
def user_settings_params
|
||||
|
|
|
@ -20,7 +20,7 @@ class Settings::ProfilesController < Settings::BaseController
|
|||
private
|
||||
|
||||
def account_params
|
||||
params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, :searchability, :birthday, :location, fields_attributes: [:name, :value])
|
||||
params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, :discoverable, :searchability, :birthday, :birth_year, :birth_month, :birth_day, :location, fields_attributes: [:name, :value])
|
||||
end
|
||||
|
||||
def set_account
|
||||
|
|
|
@ -58,6 +58,18 @@ const messages = defineMessages({
|
|||
add_or_remove_from_circle: { id: 'account.add_or_remove_from_circle', defaultMessage: 'Add or Remove from circles' },
|
||||
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
|
||||
secret: { id: 'account.secret', defaultMessage: 'Secret' },
|
||||
birth_month_1: { id: 'account.birthday.month.1', defaultMessage: 'January' },
|
||||
birth_month_2: { id: 'account.birthday.month.2', defaultMessage: 'February' },
|
||||
birth_month_3: { id: 'account.birthday.month.3', defaultMessage: 'March' },
|
||||
birth_month_4: { id: 'account.birthday.month.4', defaultMessage: 'April' },
|
||||
birth_month_5: { id: 'account.birthday.month.5', defaultMessage: 'May' },
|
||||
birth_month_6: { id: 'account.birthday.month.6', defaultMessage: 'June' },
|
||||
birth_month_7: { id: 'account.birthday.month.7', defaultMessage: 'July' },
|
||||
birth_month_8: { id: 'account.birthday.month.8', defaultMessage: 'August' },
|
||||
birth_month_9: { id: 'account.birthday.month.9', defaultMessage: 'September' },
|
||||
birth_month_10: { id: 'account.birthday.month.10', defaultMessage: 'October' },
|
||||
birth_month_11: { id: 'account.birthday.month.11', defaultMessage: 'November' },
|
||||
birth_month_12: { id: 'account.birthday.month.12', defaultMessage: 'December' },
|
||||
});
|
||||
|
||||
const dateFormatOptions = {
|
||||
|
@ -354,9 +366,38 @@ class Header extends ImmutablePureComponent {
|
|||
const hide_followers_count = account.getIn(['other_settings', 'hide_followers_count'], false);
|
||||
|
||||
const location = account.getIn(['other_settings', 'location']);
|
||||
const birthday = account.getIn(['other_settings', 'birthday']);
|
||||
const joined = account.get('created_at');
|
||||
|
||||
const birthday = (() => {
|
||||
const birth_year = account.getIn(['other_settings', 'birth_year'], null);
|
||||
const birth_month = account.getIn(['other_settings', 'birth_month'], null);
|
||||
const birth_day = account.getIn(['other_settings', 'birth_day'], null);
|
||||
|
||||
const birth_month_name = birth_month >= 1 && birth_month <= 12 ? intl.formatMessage(messages[`birth_month_${birth_month}`]) : null;
|
||||
|
||||
if (birth_year && birth_month && birth_day) {
|
||||
const date = new Date(birth_year, birth_month - 1, birth_day);
|
||||
return <Fragment><FormattedDate value={date} hour12={false} year='numeric' month='short' day='2-digit' />(<FormattedMessage id='account.age' defaultMessage='{age} years old}' values={{ age: age(date) }} />)</Fragment>;
|
||||
} else if (birth_month && birth_day) {
|
||||
return <FormattedMessage id='account.birthday.month_day' defaultMessage='{month_name} {day}' values={{ month: birth_month, day: birth_day, month_name: birth_month_name }} />;
|
||||
} else if (birth_year && birth_month) {
|
||||
return <FormattedMessage id='account.birthday.year_month' defaultMessage='{month_name}, {year}' values={{ year: birth_year, month: birth_month, month_name: birth_month_name }} />;
|
||||
} else if (birth_year) {
|
||||
return <FormattedMessage id='account.birthday.year' defaultMessage='{year}' values={{ year: birth_year }} />;
|
||||
} else if (birth_month) {
|
||||
return <FormattedMessage id='account.birthday.month' defaultMessage='{month_name}' values={{ month: birth_month, day: birth_day, month_name: birth_month_name }} />;
|
||||
} else if (birth_day) {
|
||||
return null;
|
||||
} else {
|
||||
const date = account.getIn(['other_settings', 'birthday'], null);
|
||||
if (date) {
|
||||
return <Fragment><FormattedDate value={date} hour12={false} year='numeric' month='short' day='2-digit' />(<FormattedMessage id='account.age' defaultMessage='{age} years old}' values={{ age: age(date) }} />)</Fragment>;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
return (
|
||||
<div className={classNames('account__header', { inactive: !!account.get('moved') })} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
|
||||
<div className='account__header__image'>
|
||||
|
@ -437,7 +478,7 @@ class Header extends ImmutablePureComponent {
|
|||
</tr>}
|
||||
{birthday && <tr>
|
||||
<th><Icon id='birthday-cake' fixedWidth aria-hidden='true' /> <FormattedMessage id='account.birthday' defaultMessage='Birthday' /></th>
|
||||
<td><FormattedDate value={birthday} hour12={false} year='numeric' month='short' day='2-digit' />(<FormattedMessage id='account.age' defaultMessage='{age} years old}' values={{age: age(birthday)}} />)</td>
|
||||
<td>{birthday}</td>
|
||||
</tr>}
|
||||
<tr>
|
||||
<th><Icon id='calendar' fixedWidth aria-hidden='true' /> <FormattedMessage id='account.joined' defaultMessage='Joined' /></th>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { Fragment } from 'react';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import PropTypes from 'prop-types';
|
||||
import { defineMessages, injectIntl, FormattedMessage, FormattedDate } from 'react-intl';
|
||||
|
@ -11,6 +11,18 @@ import classNames from 'classnames';
|
|||
|
||||
const messages = defineMessages({
|
||||
linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' },
|
||||
birth_month_1: { id: 'account.birthday.month.1', defaultMessage: 'January' },
|
||||
birth_month_2: { id: 'account.birthday.month.2', defaultMessage: 'February' },
|
||||
birth_month_3: { id: 'account.birthday.month.3', defaultMessage: 'March' },
|
||||
birth_month_4: { id: 'account.birthday.month.4', defaultMessage: 'April' },
|
||||
birth_month_5: { id: 'account.birthday.month.5', defaultMessage: 'May' },
|
||||
birth_month_6: { id: 'account.birthday.month.6', defaultMessage: 'June' },
|
||||
birth_month_7: { id: 'account.birthday.month.7', defaultMessage: 'July' },
|
||||
birth_month_8: { id: 'account.birthday.month.8', defaultMessage: 'August' },
|
||||
birth_month_9: { id: 'account.birthday.month.9', defaultMessage: 'September' },
|
||||
birth_month_10: { id: 'account.birthday.month.10', defaultMessage: 'October' },
|
||||
birth_month_11: { id: 'account.birthday.month.11', defaultMessage: 'November' },
|
||||
birth_month_12: { id: 'account.birthday.month.12', defaultMessage: 'December' },
|
||||
});
|
||||
|
||||
const dateFormatOptions = {
|
||||
|
@ -52,9 +64,38 @@ class HeaderExtra extends ImmutablePureComponent {
|
|||
const fields = account.get('fields');
|
||||
|
||||
const location = account.getIn(['other_settings', 'location']);
|
||||
const birthday = account.getIn(['other_settings', 'birthday']);
|
||||
const joined = account.get('created_at');
|
||||
|
||||
const birthday = (() => {
|
||||
const birth_year = account.getIn(['other_settings', 'birth_year'], null);
|
||||
const birth_month = account.getIn(['other_settings', 'birth_month'], null);
|
||||
const birth_day = account.getIn(['other_settings', 'birth_day'], null);
|
||||
|
||||
const birth_month_name = birth_month >= 1 && birth_month <= 12 ? intl.formatMessage(messages[`birth_month_${birth_month}`]) : null;
|
||||
|
||||
if (birth_year && birth_month && birth_day) {
|
||||
const date = new Date(birth_year, birth_month - 1, birth_day);
|
||||
return <Fragment><FormattedDate value={date} hour12={false} year='numeric' month='short' day='2-digit' />(<FormattedMessage id='account.age' defaultMessage='{age} years old}' values={{ age: age(date) }} />)</Fragment>;
|
||||
} else if (birth_month && birth_day) {
|
||||
return <FormattedMessage id='account.birthday.month_day' defaultMessage='{month_name} {day}' values={{ month: birth_month, day: birth_day, month_name: birth_month_name }} />;
|
||||
} else if (birth_year && birth_month) {
|
||||
return <FormattedMessage id='account.birthday.year_month' defaultMessage='{month_name}, {year}' values={{ year: birth_year, month: birth_month, month_name: birth_month_name }} />;
|
||||
} else if (birth_year) {
|
||||
return <FormattedMessage id='account.birthday.year' defaultMessage='{year}' values={{ year: birth_year }} />;
|
||||
} else if (birth_month) {
|
||||
return <FormattedMessage id='account.birthday.month' defaultMessage='{month_name}' values={{ month: birth_month, day: birth_day, month_name: birth_month_name }} />;
|
||||
} else if (birth_day) {
|
||||
return null;
|
||||
} else {
|
||||
const date = account.getIn(['other_settings', 'birthday'], null);
|
||||
if (date) {
|
||||
return <Fragment><FormattedDate value={date} hour12={false} year='numeric' month='short' day='2-digit' />(<FormattedMessage id='account.age' defaultMessage='{age} years old}' values={{ age: age(date) }} />)</Fragment>;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
return (
|
||||
<div className={classNames('account__header', 'advanced', { inactive: !!account.get('moved') })}>
|
||||
<div className='account__header__extra'>
|
||||
|
@ -98,7 +139,7 @@ class HeaderExtra extends ImmutablePureComponent {
|
|||
</tr>}
|
||||
{birthday && <tr>
|
||||
<th><Icon id='birthday-cake' fixedWidth aria-hidden='true' /> <FormattedMessage id='account.birthday' defaultMessage='Birthday' /></th>
|
||||
<td><FormattedDate value={birthday} hour12={false} year='numeric' month='short' day='2-digit' />(<FormattedMessage id='account.age' defaultMessage='{age} years old}' values={{ age: age(birthday) }} />)</td>
|
||||
<td>{birthday}</td>
|
||||
</tr>}
|
||||
<tr>
|
||||
<th><Icon id='calendar' fixedWidth aria-hidden='true' /> <FormattedMessage id='account.joined' defaultMessage='Joined' /></th>
|
||||
|
|
|
@ -6,6 +6,22 @@
|
|||
"account.badges.bot": "Bot",
|
||||
"account.badges.group": "Group",
|
||||
"account.birthday": "Birthday",
|
||||
"account.birthday.month": "{month_name}",
|
||||
"account.birthday.month.1": "January",
|
||||
"account.birthday.month.2": "February",
|
||||
"account.birthday.month.3": "March",
|
||||
"account.birthday.month.4": "April",
|
||||
"account.birthday.month.5": "May",
|
||||
"account.birthday.month.6": "June",
|
||||
"account.birthday.month.7": "July",
|
||||
"account.birthday.month.8": "August",
|
||||
"account.birthday.month.9": "September",
|
||||
"account.birthday.month.10": "October",
|
||||
"account.birthday.month.11": "November",
|
||||
"account.birthday.month.12": "December",
|
||||
"account.birthday.month_day": "{month_name} {day}",
|
||||
"account.birthday.year": "{year}",
|
||||
"account.birthday.year_month": "{month_name}, {year}",
|
||||
"account.block": "Block @{name}",
|
||||
"account.block_domain": "Block domain {domain}",
|
||||
"account.blocked": "Blocked",
|
||||
|
|
|
@ -6,6 +6,22 @@
|
|||
"account.badges.bot": "Bot",
|
||||
"account.badges.group": "Group",
|
||||
"account.birthday": "誕生日",
|
||||
"account.birthday.month": "{month}月",
|
||||
"account.birthday.month.1": "睦月",
|
||||
"account.birthday.month.2": "如月",
|
||||
"account.birthday.month.3": "弥生",
|
||||
"account.birthday.month.4": "卯月",
|
||||
"account.birthday.month.5": "皐月",
|
||||
"account.birthday.month.6": "水無月",
|
||||
"account.birthday.month.7": "文月",
|
||||
"account.birthday.month.8": "葉月",
|
||||
"account.birthday.month.9": "長月",
|
||||
"account.birthday.month.10": "神無月",
|
||||
"account.birthday.month.11": "霜月",
|
||||
"account.birthday.month.12": "師走",
|
||||
"account.birthday.month_day": "{month}月{day}日",
|
||||
"account.birthday.year": "{year}年",
|
||||
"account.birthday.year_month": "{year}年{month}月",
|
||||
"account.block": "@{name}さんをブロック",
|
||||
"account.block_domain": "{domain}全体をブロック",
|
||||
"account.blocked": "ブロック済み",
|
||||
|
|
|
@ -293,6 +293,14 @@ code {
|
|||
flex: 1 1 auto;
|
||||
min-height: 1px;
|
||||
|
||||
&-2 {
|
||||
max-width: 16.7%;
|
||||
}
|
||||
|
||||
&-4 {
|
||||
max-width: 33.3%;
|
||||
}
|
||||
|
||||
&-6 {
|
||||
max-width: 50%;
|
||||
}
|
||||
|
@ -301,6 +309,10 @@ code {
|
|||
max-width: 66.67%;
|
||||
}
|
||||
|
||||
&-12 {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.actions {
|
||||
margin-top: 27px;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,49 @@ module AccountSettings
|
|||
end
|
||||
|
||||
def birthday=(val)
|
||||
settings['birthday'] = ActiveRecord::Type::Date.new.cast(val)
|
||||
set_birthday(val)
|
||||
end
|
||||
|
||||
def birth_year
|
||||
settings['birth_year'] || birthday && ActiveRecord::Type::Date.new.cast(birthday).year
|
||||
end
|
||||
|
||||
def birth_year=(val)
|
||||
settings['birth_year'] = Integer(val).then { |val| (0..9999).cover?(val) ? val : nil } rescue nil
|
||||
normalize_birthday
|
||||
end
|
||||
|
||||
def birth_month
|
||||
settings['birth_month'] || birthday && ActiveRecord::Type::Date.new.cast(birthday).month
|
||||
end
|
||||
|
||||
def birth_month=(val)
|
||||
settings['birth_month'] = Integer(val).then { |val| (1..12).cover?(val) ? val : nil } rescue nil
|
||||
normalize_birthday
|
||||
end
|
||||
|
||||
def birth_day
|
||||
settings['birth_day'] || birthday && ActiveRecord::Type::Date.new.cast(birthday).day
|
||||
end
|
||||
|
||||
def birth_day=(val)
|
||||
settings['birth_day'] = Integer(val).then { |val| (1..31).cover?(val) ? val : nil } rescue nil
|
||||
normalize_birthday
|
||||
end
|
||||
|
||||
def normalize_birthday
|
||||
date = Date.new(settings['birth_year'], settings['birth_month'], settings['birth_day']) rescue nil
|
||||
set_birthday(date)
|
||||
end
|
||||
|
||||
def set_birthday(val)
|
||||
date = ActiveRecord::Type::Date.new.cast(val)
|
||||
|
||||
if date.class.name === 'Date'
|
||||
settings['birthday'] = date
|
||||
else
|
||||
settings.delete('birthday')
|
||||
end
|
||||
end
|
||||
|
||||
def location
|
||||
|
|
|
@ -27,7 +27,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
|
|||
attribute :moved_to, if: :moved?
|
||||
attribute :also_known_as, if: :also_known_as?
|
||||
attribute :suspended, if: :suspended?
|
||||
attribute :bday, key: :'vcard:bday'
|
||||
attribute :bday, key: :'vcard:bday', if: :bday?
|
||||
attribute :address, key: :'vcard:Address'
|
||||
|
||||
has_many :virtual_other_settings, key: :other_setting
|
||||
|
@ -177,6 +177,10 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
|
|||
object.birthday
|
||||
end
|
||||
|
||||
def bday?
|
||||
object.birthday
|
||||
end
|
||||
|
||||
def address
|
||||
object.location
|
||||
end
|
||||
|
|
|
@ -260,6 +260,9 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||
|
||||
DEFER_SETTINGS_KEYS = %w(
|
||||
birthday
|
||||
birth_year
|
||||
birth_month
|
||||
birth_day
|
||||
location
|
||||
cat_ears_color
|
||||
noindex
|
||||
|
|
|
@ -60,8 +60,14 @@
|
|||
%p.warning-hint= t('simple_form.hints.defaults.searchability')
|
||||
|
||||
.fields-row
|
||||
.fields-row__column.fields-group.fields-row__column-8
|
||||
= f.input :birthday, wrapper: :with_label, input_html: { placeholder: '2016-03-16', pattern: '\d{4}-\d{1,2}-\d{1,2}' }, hint: t('simple_form.hints.defaults.birthday'), fedibird_features: true
|
||||
.fields-row__column.fields-group.fields-row__column-2
|
||||
= f.input :birth_year, wrapper: :with_label, input_html: { pattern: '\d{1,4}' }, hint: t('simple_form.hints.defaults.birth_year'), fedibird_features: true
|
||||
.fields-row__column.fields-group.fields-row__column-2
|
||||
= f.input :birth_month, wrapper: :with_label, input_html: { pattern: '\d{1,2}' }, hint: t('simple_form.hints.defaults.birth_month'), fedibird_features: true
|
||||
.fields-row__column.fields-group.fields-row__column-2
|
||||
= f.input :birth_day, wrapper: :with_label, input_html: { pattern: '\d{1,2}' }, hint: t('simple_form.hints.defaults.birth_day'), fedibird_features: true
|
||||
.fields-row__column.fields-group.fields-row__column-6
|
||||
%p.hint= t('simple_form.hints.defaults.birth_description')
|
||||
%p.warning-hint= t('simple_form.hints.defaults.birthday_caution')
|
||||
|
||||
.fields-row
|
||||
|
|
|
@ -33,8 +33,11 @@ en:
|
|||
defaults:
|
||||
autofollow: People who sign up through the invite will automatically follow you
|
||||
avatar: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px
|
||||
birthday: Specify the date of birth in the format yyyy-mm-dd(ex. 2016-03-16)
|
||||
birthday_caution: It will be published on the Internet. Please handle your personal information with care
|
||||
birthday_caution: It will be published on the Internet. Please handle your personal information with care.
|
||||
birth_day: 1-31
|
||||
birth_month: 1-12
|
||||
birth_year: 0-9999
|
||||
birth_description: Specify the date of birth. If you enter a full date, it is compatible with Misskey.
|
||||
bot: Signal to others that the account mainly performs automated actions and might not be monitored
|
||||
context: One or multiple contexts where the filter should apply
|
||||
current_password: For security purposes please enter the password of the current account
|
||||
|
@ -48,7 +51,7 @@ en:
|
|||
irreversible: Filtered posts will disappear irreversibly, even if filter is later removed
|
||||
locale: The language of the user interface, e-mails and push notifications
|
||||
location: Area of primary residence or activity
|
||||
location_caution: It will be published on the Internet. Please do not include detailed addresses except for business use
|
||||
location_caution: It will be published on the Internet. Please do not include detailed addresses except for business use.
|
||||
locked: Manually control who can follow you by approving follow requests
|
||||
password: Use at least 8 characters
|
||||
phrase: Will be matched regardless of casing in text or content warning of a post
|
||||
|
@ -218,6 +221,9 @@ en:
|
|||
autofollow: Invite to follow your account
|
||||
avatar: Avatar
|
||||
birthday: Birthday
|
||||
birth_day: Birth day
|
||||
birth_month: Birth month
|
||||
birth_year: Birth year
|
||||
bot: This is a bot account
|
||||
chosen_languages: Filter languages
|
||||
confirm_new_password: Confirm new password
|
||||
|
|
|
@ -33,8 +33,11 @@ ja:
|
|||
defaults:
|
||||
autofollow: 招待から登録した人が自動的にあなたをフォローするようになります
|
||||
avatar: "%{size}までのPNG、GIF、JPGが利用可能です。%{dimensions}pxまで縮小されます"
|
||||
birthday: 誕生日を年月日の順にyyyy-mm-dd(ex. 2016-03-16)という書式で指定します
|
||||
birthday_caution: インターネットに公開されます。個人情報は慎重に取り扱ってください
|
||||
birthday_caution: インターネットに公開されます。個人情報は慎重に取り扱ってください。
|
||||
birth_day: 1〜31
|
||||
birth_month: 1〜12
|
||||
birth_year: 0〜9999
|
||||
birth_description: 誕生日を指定します。完全な日付を入力した場合はMisskeyと互換性があります。
|
||||
bot: このアカウントは主に自動で動作し、人が見ていない可能性があります
|
||||
context: フィルターを適用する対象 (複数選択可)
|
||||
current_password: 現在のアカウントのパスワードを入力してください
|
||||
|
@ -48,7 +51,7 @@ ja:
|
|||
irreversible: フィルターが後で削除されても、除外された投稿は元に戻せなくなります
|
||||
locale: ユーザーインターフェース、メールやプッシュ通知の言語
|
||||
location: 主に居住・活動する地域・場所
|
||||
location_caution: インターネットに公開されます。ビジネス用途を除き詳細な住所を記載しないでください
|
||||
location_caution: インターネットに公開されます。ビジネス用途を除き詳細な住所を記載しないでください。
|
||||
locked: フォロワーを手動で承認する必要があります
|
||||
password: 少なくとも8文字は入力してください
|
||||
phrase: 投稿内容の大文字小文字や閲覧注意に関係なく一致
|
||||
|
@ -214,6 +217,9 @@ ja:
|
|||
autofollow: 招待から参加後、あなたをフォロー
|
||||
avatar: アイコン
|
||||
birthday: 誕生日
|
||||
birth_day: 誕生日
|
||||
birth_month: 誕生月
|
||||
birth_year: 誕生年
|
||||
bot: これは BOT アカウントです
|
||||
chosen_languages: 表示する言語
|
||||
confirm_new_password: 新しいパスワード(確認用)
|
||||
|
|
Loading…
Reference in New Issue