diff options
Diffstat (limited to 'app')
8 files changed, 100 insertions, 23 deletions
diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.js b/app/javascript/mastodon/features/notifications/components/column_settings.js index a334fd63c..60a86312a 100644 --- a/app/javascript/mastodon/features/notifications/components/column_settings.js +++ b/app/javascript/mastodon/features/notifications/components/column_settings.js @@ -89,6 +89,17 @@ export default class ColumnSettings extends React.PureComponent { <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'reblog']} onChange={onChange} label={soundStr} /> </div> </div> + + <div role='group' aria-labelledby='notifications-poll'> + <span id='notifications-poll' className='column-settings__section'><FormattedMessage id='notifications.column_settings.poll' defaultMessage='Poll results:' /></span> + + <div className='column-settings__row'> + <SettingToggle prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'poll']} onChange={onChange} label={alertStr} /> + {showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'poll']} onChange={this.onPushChange} label={pushStr} />} + <SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'poll']} onChange={onChange} label={showStr} /> + <SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'poll']} onChange={onChange} label={soundStr} /> + </div> + </div> </div> ); } diff --git a/app/javascript/mastodon/features/notifications/components/filter_bar.js b/app/javascript/mastodon/features/notifications/components/filter_bar.js index 6ae8b7491..3f3e6ab7d 100644 --- a/app/javascript/mastodon/features/notifications/components/filter_bar.js +++ b/app/javascript/mastodon/features/notifications/components/filter_bar.js @@ -7,6 +7,7 @@ const tooltips = defineMessages({ mentions: { id: 'notifications.filter.mentions', defaultMessage: 'Mentions' }, favourites: { id: 'notifications.filter.favourites', defaultMessage: 'Favourites' }, boosts: { id: 'notifications.filter.boosts', defaultMessage: 'Boosts' }, + polls: { id: 'notifications.filter.polls', defaultMessage: 'Poll results' }, follows: { id: 'notifications.filter.follows', defaultMessage: 'Follows' }, }); @@ -80,6 +81,13 @@ class FilterBar extends React.PureComponent { <Icon id='retweet' fixedWidth /> </button> <button + className={selectedFilter === 'poll' ? 'active' : ''} + onClick={this.onClick('poll')} + title={intl.formatMessage(tooltips.polls)} + > + <Icon id='tasks' fixedWidth /> + </button> + <button className={selectedFilter === 'follow' ? 'active' : ''} onClick={this.onClick('follow')} title={intl.formatMessage(tooltips.follows)} diff --git a/app/javascript/mastodon/features/notifications/components/notification.js b/app/javascript/mastodon/features/notifications/components/notification.js index 61023bed6..4bdf09166 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.js +++ b/app/javascript/mastodon/features/notifications/components/notification.js @@ -210,14 +210,14 @@ class Notification extends ImmutablePureComponent { return ( <HotKeys handlers={this.getHandlers()}> - <div className='notification notification-poll focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.poll', defaultMessage: 'Your poll has ended' }), notification.get('created_at'))}> + <div className='notification notification-poll focusable' tabIndex='0' aria-label={notificationForScreenReader(intl, intl.formatMessage({ id: 'notification.poll', defaultMessage: 'A poll you have voted in has ended' }), notification.get('created_at'))}> <div className='notification__message'> <div className='notification__favourite-icon-wrapper'> <Icon id='tasks' fixedWidth /> </div> <span title={notification.get('created_at')}> - <FormattedMessage id='notification.poll' defaultMessage='Your poll has ended' /> + <FormattedMessage id='notification.poll' defaultMessage='A poll you have voted in has ended' /> </span> </div> diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index 868e54751..78a5648af 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -17,6 +17,10 @@ { "defaultMessage": "File upload limit exceeded.", "id": "upload_error.limit" + }, + { + "defaultMessage": "File upload not allowed with polls.", + "id": "upload_error.poll" } ], "path": "app/javascript/mastodon/actions/compose.json" @@ -910,6 +914,52 @@ { "descriptors": [ { + "defaultMessage": "Add a poll", + "id": "poll_button.add_poll" + }, + { + "defaultMessage": "Remove poll", + "id": "poll_button.remove_poll" + } + ], + "path": "app/javascript/mastodon/features/compose/components/poll_button.json" + }, + { + "descriptors": [ + { + "defaultMessage": "Choice {number}", + "id": "compose_form.poll.option_placeholder" + }, + { + "defaultMessage": "Add a choice", + "id": "compose_form.poll.add_option" + }, + { + "defaultMessage": "Remove this choice", + "id": "compose_form.poll.remove_option" + }, + { + "defaultMessage": "Poll duration", + "id": "compose_form.poll.duration" + }, + { + "defaultMessage": "{number, plural, one {# minute} other {# minutes}}", + "id": "intervals.full.minutes" + }, + { + "defaultMessage": "{number, plural, one {# hour} other {# hours}}", + "id": "intervals.full.hours" + }, + { + "defaultMessage": "{number, plural, one {# day} other {# days}}", + "id": "intervals.full.days" + } + ], + "path": "app/javascript/mastodon/features/compose/components/poll_form.json" + }, + { + "descriptors": [ + { "defaultMessage": "Public", "id": "privacy.public.short" }, @@ -1853,6 +1903,10 @@ { "defaultMessage": "{name} boosted your status", "id": "notification.reblog" + }, + { + "defaultMessage": "Your poll has ended", + "id": "notification.poll" } ], "path": "app/javascript/mastodon/features/notifications/components/notification.json" @@ -1917,24 +1971,6 @@ { "descriptors": [ { - "defaultMessage": "A look inside...", - "id": "standalone.public_title" - } - ], - "path": "app/javascript/mastodon/features/standalone/community_timeline/index.json" - }, - { - "descriptors": [ - { - "defaultMessage": "A look inside...", - "id": "standalone.public_title" - } - ], - "path": "app/javascript/mastodon/features/standalone/public_timeline/index.json" - }, - { - "descriptors": [ - { "defaultMessage": "Delete", "id": "status.delete" }, diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 822c1ee50..eb82cd9a9 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -77,6 +77,10 @@ "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.", "compose_form.lock_disclaimer.lock": "locked", "compose_form.placeholder": "What's on your mind?", + "compose_form.poll.add_option": "Add a choice", + "compose_form.poll.duration": "Poll duration", + "compose_form.poll.option_placeholder": "Choice {number}", + "compose_form.poll.remove_option": "Remove this choice", "compose_form.publish": "Toot", "compose_form.publish_loud": "{publish}!", "compose_form.sensitive.marked": "Media is marked as sensitive", @@ -155,6 +159,9 @@ "home.column_settings.basic": "Basic", "home.column_settings.show_reblogs": "Show boosts", "home.column_settings.show_replies": "Show replies", + "intervals.full.days": "{number, plural, one {# day} other {# days}}", + "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}", + "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}", "introduction.federation.action": "Next", "introduction.federation.federated.headline": "Federated", "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.", @@ -245,7 +252,7 @@ "notification.favourite": "{name} favourited your status", "notification.follow": "{name} followed you", "notification.mention": "{name} mentioned you", - "notification.poll": "Your poll has ended", + "notification.poll": "A poll you have voted in has ended", "notification.reblog": "{name} boosted your status", "notifications.clear": "Clear notifications", "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?", @@ -270,6 +277,8 @@ "poll.refresh": "Refresh", "poll.total_votes": "{count, plural, one {# vote} other {# votes}}", "poll.vote": "Vote", + "poll_button.add_poll": "Add a poll", + "poll_button.remove_poll": "Remove poll", "privacy.change": "Adjust status privacy", "privacy.direct.long": "Post to mentioned users only", "privacy.direct.short": "Direct", @@ -304,7 +313,6 @@ "search_results.hashtags": "Hashtags", "search_results.statuses": "Toots", "search_results.total": "{count, number} {count, plural, one {result} other {results}}", - "standalone.public_title": "A look inside...", "status.admin_account": "Open moderation interface for @{name}", "status.admin_status": "Open this status in the moderation interface", "status.block": "Block @{name}", @@ -362,6 +370,7 @@ "upload_area.title": "Drag & drop to upload", "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_error.limit": "File upload limit exceeded.", + "upload_error.poll": "File upload not allowed with polls.", "upload_form.description": "Describe for the visually impaired", "upload_form.focus": "Change preview", "upload_form.undo": "Delete", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index e2d3a98f3..6388c7e9c 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -77,6 +77,10 @@ "compose_form.lock_disclaimer": "あなたのアカウントは{locked}になっていません。誰でもあなたをフォローすることができ、フォロワー限定の投稿を見ることができます。", "compose_form.lock_disclaimer.lock": "承認制", "compose_form.placeholder": "今なにしてる?", + "compose_form.poll.add_option": "Add a choice", + "compose_form.poll.duration": "Poll duration", + "compose_form.poll.option_placeholder": "Choice {number}", + "compose_form.poll.remove_option": "Remove this choice", "compose_form.publish": "トゥート", "compose_form.publish_loud": "{publish}!", "compose_form.sensitive.marked": "メディアに閲覧注意が設定されています", @@ -155,6 +159,9 @@ "home.column_settings.basic": "基本設定", "home.column_settings.show_reblogs": "ブースト表示", "home.column_settings.show_replies": "返信表示", + "intervals.full.days": "{number, plural, one {# day} other {# days}}", + "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}", + "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}", "introduction.federation.action": "次へ", "introduction.federation.federated.headline": "連合タイムライン", "introduction.federation.federated.text": "Fediverseの他のサーバーからの公開投稿は連合タイムラインに表示されます。", @@ -245,6 +252,7 @@ "notification.favourite": "{name}さんがあなたのトゥートをお気に入りに登録しました", "notification.follow": "{name}さんにフォローされました", "notification.mention": "{name}さんがあなたに返信しました", + "notification.poll": "Your poll has ended", "notification.reblog": "{name}さんがあなたのトゥートをブーストしました", "notifications.clear": "通知を消去", "notifications.clear_confirmation": "本当に通知を消去しますか?", @@ -269,6 +277,8 @@ "poll.refresh": "Refresh", "poll.total_votes": "{count, plural, one {# vote} other {# votes}}", "poll.vote": "Vote", + "poll_button.add_poll": "Add a poll", + "poll_button.remove_poll": "Remove poll", "privacy.change": "公開範囲を変更", "privacy.direct.long": "メンションしたユーザーだけに公開", "privacy.direct.short": "ダイレクト", @@ -303,7 +313,6 @@ "search_results.hashtags": "ハッシュタグ", "search_results.statuses": "トゥート", "search_results.total": "{count, number}件の結果", - "standalone.public_title": "今こんな話をしています...", "status.admin_account": "@{name} のモデレーション画面を開く", "status.admin_status": "このトゥートをモデレーション画面で開く", "status.block": "@{name}さんをブロック", @@ -361,6 +370,7 @@ "upload_area.title": "ドラッグ&ドロップでアップロード", "upload_button.label": "メディアを追加 (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_error.limit": "アップロードできる上限を超えています。", + "upload_error.poll": "File upload not allowed with polls.", "upload_form.description": "視覚障害者のための説明", "upload_form.focus": "焦点", "upload_form.undo": "削除", diff --git a/app/javascript/mastodon/reducers/push_notifications.js b/app/javascript/mastodon/reducers/push_notifications.js index 85628c6b1..317352b79 100644 --- a/app/javascript/mastodon/reducers/push_notifications.js +++ b/app/javascript/mastodon/reducers/push_notifications.js @@ -9,6 +9,7 @@ const initialState = Immutable.Map({ favourite: false, reblog: false, mention: false, + poll: false, }), isSubscribed: false, browserSupport: false, diff --git a/app/models/poll.rb b/app/models/poll.rb index 09f0b65ec..6df230337 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -26,6 +26,8 @@ class Poll < ApplicationRecord has_many :votes, class_name: 'PollVote', inverse_of: :poll, dependent: :destroy + has_many :notifications, as: :activity, dependent: :destroy + validates :options, presence: true validates :expires_at, presence: true, if: :local? validates_with PollValidator, on: :create, if: :local? |