about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/javascript/flavours/glitch/reducers/statuses.js6
-rw-r--r--app/javascript/mastodon/components/scrollable_list.js2
-rw-r--r--app/javascript/mastodon/features/status/components/card.js2
-rw-r--r--app/javascript/mastodon/locales/defaultMessages.json47
-rw-r--r--app/javascript/mastodon/locales/en.json12
-rw-r--r--app/javascript/mastodon/locales/ja.json15
-rw-r--r--app/javascript/mastodon/reducers/statuses.js4
-rw-r--r--app/lib/activitypub/activity/create.rb2
-rw-r--r--app/services/activitypub/process_account_service.rb2
-rw-r--r--app/services/fetch_link_card_service.rb9
10 files changed, 80 insertions, 21 deletions
diff --git a/app/javascript/flavours/glitch/reducers/statuses.js b/app/javascript/flavours/glitch/reducers/statuses.js
index 617d96e5d..1beaf73e1 100644
--- a/app/javascript/flavours/glitch/reducers/statuses.js
+++ b/app/javascript/flavours/glitch/reducers/statuses.js
@@ -118,15 +118,15 @@ export default function statuses(state = initialState, action) {
   case FAVOURITE_REQUEST:
     return state.setIn([action.status.get('id'), 'favourited'], true);
   case FAVOURITE_FAIL:
-    return state.setIn([action.status.get('id'), 'favourited'], false);
+    return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'favourited'], false);
   case BOOKMARK_REQUEST:
     return state.setIn([action.status.get('id'), 'bookmarked'], true);
   case BOOKMARK_FAIL:
-    return state.setIn([action.status.get('id'), 'bookmarked'], false);
+    return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'bookmarked'], false);
   case REBLOG_REQUEST:
     return state.setIn([action.status.get('id'), 'reblogged'], true);
   case REBLOG_FAIL:
-    return state.setIn([action.status.get('id'), 'reblogged'], false);
+    return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'reblogged'], false);
   case STATUS_MUTE_SUCCESS:
     return state.setIn([action.id, 'muted'], true);
   case STATUS_UNMUTE_SUCCESS:
diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.js
index 7551d0b1f..ab4e7d59c 100644
--- a/app/javascript/mastodon/components/scrollable_list.js
+++ b/app/javascript/mastodon/components/scrollable_list.js
@@ -136,7 +136,7 @@ export default class ScrollableList extends PureComponent {
       React.Children.count(prevProps.children) < React.Children.count(this.props.children) &&
       this.getFirstChildKey(prevProps) !== this.getFirstChildKey(this.props);
 
-    if ((someItemInserted && this.node.scrollTop > 0) || this.mouseMovedRecently) {
+    if (someItemInserted && (this.node.scrollTop > 0 || this.mouseMovedRecently)) {
       return this.node.scrollHeight - this.node.scrollTop;
     } else {
       return null;
diff --git a/app/javascript/mastodon/features/status/components/card.js b/app/javascript/mastodon/features/status/components/card.js
index 743fe779a..235d209b8 100644
--- a/app/javascript/mastodon/features/status/components/card.js
+++ b/app/javascript/mastodon/features/status/components/card.js
@@ -73,7 +73,7 @@ export default class Card extends React.PureComponent {
   };
 
   componentWillReceiveProps (nextProps) {
-    if (this.props.card !== nextProps.card) {
+    if (!Immutable.is(this.props.card, nextProps.card)) {
       this.setState({ embedded: false });
     }
   }
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index ec2d38a47..57988fbd8 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -349,6 +349,10 @@
       {
         "defaultMessage": "{name} boosted",
         "id": "status.reblogged_by"
+      },
+      {
+        "defaultMessage": "Show thread",
+        "id": "status.show_thread"
       }
     ],
     "path": "app/javascript/mastodon/components/status.json"
@@ -474,6 +478,15 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "No toots here!",
+        "id": "empty_column.account_timeline"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/account_timeline/index.json"
+  },
+  {
+    "descriptors": [
+      {
         "defaultMessage": "Mention @{name}",
         "id": "account.mention"
       },
@@ -578,6 +591,7 @@
         "id": "account.unendorse"
       },
       {
+        "defaultMessage": "Add or Remove from lists",
         "id": "account.add_or_remove_from_list"
       },
       {
@@ -1278,6 +1292,39 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "Any of these",
+        "id": "hashtag.column_settings.tag_mode.any"
+      },
+      {
+        "defaultMessage": "All of these",
+        "id": "hashtag.column_settings.tag_mode.all"
+      },
+      {
+        "defaultMessage": "None of these",
+        "id": "hashtag.column_settings.tag_mode.none"
+      },
+      {
+        "defaultMessage": "Include additional tags in this column",
+        "id": "hashtag.column_settings.tag_toggle"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/hashtag_timeline/components/column_settings.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "or {additional}",
+        "id": "hashtag.column_header.tag_mode.any"
+      },
+      {
+        "defaultMessage": "and {additional}",
+        "id": "hashtag.column_header.tag_mode.all"
+      },
+      {
+        "defaultMessage": "without {additional}",
+        "id": "hashtag.column_header.tag_mode.none"
+      },
+      {
         "defaultMessage": "There is nothing in this hashtag yet.",
         "id": "empty_column.hashtag"
       }
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index bd41b9714..16f680fa3 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -116,6 +116,7 @@
   "emoji_button.search_results": "Search results",
   "emoji_button.symbols": "Symbols",
   "emoji_button.travel": "Travel & Places",
+  "empty_column.account_timeline": "No toots here!",
   "empty_column.blocks": "You haven't blocked any users yet.",
   "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
   "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
@@ -141,13 +142,13 @@
   "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
   "getting_started.security": "Security",
   "getting_started.terms": "Terms of service",
-  "hashtag.column_settings.tag_toggle": "Include additional tags for this column",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
-  "hashtag.column_header.tag_mode.any": "{tag} or {additional}",
   "hashtag.column_header.tag_mode.all": "{tag} and {additional}",
+  "hashtag.column_header.tag_mode.any": "{tag} or {additional}",
   "hashtag.column_header.tag_mode.none": "{tag} without {additional}",
+  "hashtag.column_settings.tag_mode.all": "All of these",
+  "hashtag.column_settings.tag_mode.any": "Any of these",
+  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_settings.tag_toggle": "Include additional tags for this column",
   "home.column_settings.basic": "Basic",
   "home.column_settings.show_reblogs": "Show boosts",
   "home.column_settings.show_replies": "Show replies",
@@ -325,6 +326,7 @@
   "status.show_less_all": "Show less for all",
   "status.show_more": "Show more",
   "status.show_more_all": "Show more for all",
+  "status.show_thread": "Show thread",
   "status.unmute_conversation": "Unmute conversation",
   "status.unpin": "Unpin from profile",
   "suggestions.dismiss": "Dismiss suggestion",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index a964d6133..a79f9db86 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -1,5 +1,5 @@
 {
-  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.add_or_remove_from_list": "リストに追加または外す",
   "account.badges.bot": "Bot",
   "account.block": "@{name}さんをブロック",
   "account.block_domain": "{domain}全体を非表示",
@@ -116,6 +116,7 @@
   "emoji_button.search_results": "検索結果",
   "emoji_button.symbols": "記号",
   "emoji_button.travel": "旅行と場所",
+  "empty_column.account_timeline": "トゥートがありません!",
   "empty_column.blocks": "まだ誰もブロックしていません。",
   "empty_column.community": "ローカルタイムラインはまだ使われていません。何か書いてみましょう!",
   "empty_column.direct": "ダイレクトメッセージはまだありません。ダイレクトメッセージをやりとりすると、ここに表示されます。",
@@ -141,6 +142,13 @@
   "getting_started.open_source_notice": "Mastodonはオープンソースソフトウェアです。誰でもGitHub({github})から開発に参加したり、問題を報告したりできます。",
   "getting_started.security": "セキュリティ",
   "getting_started.terms": "プライバシーポリシー",
+  "hashtag.column_header.tag_mode.all": " と {additional}",
+  "hashtag.column_header.tag_mode.any": " か {additional}",
+  "hashtag.column_header.tag_mode.none": " ({additional} を除く)",
+  "hashtag.column_settings.tag_mode.all": "すべてを含む",
+  "hashtag.column_settings.tag_mode.any": "いずれかを含む",
+  "hashtag.column_settings.tag_mode.none": "これらを除く",
+  "hashtag.column_settings.tag_toggle": "このカラムに追加のタグを含める",
   "home.column_settings.basic": "基本設定",
   "home.column_settings.show_reblogs": "ブースト表示",
   "home.column_settings.show_replies": "返信表示",
@@ -318,10 +326,11 @@
   "status.show_less_all": "全て隠す",
   "status.show_more": "もっと見る",
   "status.show_more_all": "全て見る",
+  "status.show_thread": "続きを読む",
   "status.unmute_conversation": "会話のミュートを解除",
   "status.unpin": "プロフィールの固定表示を解除",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
+  "suggestions.dismiss": "隠す",
+  "suggestions.header": "興味あるかもしれません…",
   "tabs_bar.federated_timeline": "連合",
   "tabs_bar.home": "ホーム",
   "tabs_bar.local_timeline": "ローカル",
diff --git a/app/javascript/mastodon/reducers/statuses.js b/app/javascript/mastodon/reducers/statuses.js
index 6e3d830da..885cc221c 100644
--- a/app/javascript/mastodon/reducers/statuses.js
+++ b/app/javascript/mastodon/reducers/statuses.js
@@ -38,11 +38,11 @@ export default function statuses(state = initialState, action) {
   case FAVOURITE_REQUEST:
     return state.setIn([action.status.get('id'), 'favourited'], true);
   case FAVOURITE_FAIL:
-    return state.setIn([action.status.get('id'), 'favourited'], false);
+    return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'favourited'], false);
   case REBLOG_REQUEST:
     return state.setIn([action.status.get('id'), 'reblogged'], true);
   case REBLOG_FAIL:
-    return state.setIn([action.status.get('id'), 'reblogged'], false);
+    return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'reblogged'], false);
   case STATUS_MUTE_SUCCESS:
     return state.setIn([action.id, 'muted'], true);
   case STATUS_UNMUTE_SUCCESS:
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index 45079e2b3..9d2ddd3f6 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -177,7 +177,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     updated   = tag['updated']
     emoji     = CustomEmoji.find_by(shortcode: shortcode, domain: @account.domain)
 
-    return unless emoji.nil? || image_url != emoji.image_remote_url || (updated && emoji.updated_at >= updated)
+    return unless emoji.nil? || image_url != emoji.image_remote_url || (updated && updated >= emoji.updated_at)
 
     emoji ||= CustomEmoji.new(domain: @account.domain, shortcode: shortcode, uri: uri)
     emoji.image_remote_url = image_url
diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb
index c77858f1d..5c865dae2 100644
--- a/app/services/activitypub/process_account_service.rb
+++ b/app/services/activitypub/process_account_service.rb
@@ -232,7 +232,7 @@ class ActivityPub::ProcessAccountService < BaseService
     updated   = tag['updated']
     emoji     = CustomEmoji.find_by(shortcode: shortcode, domain: @account.domain)
 
-    return unless emoji.nil? || image_url != emoji.image_remote_url || (updated && emoji.updated_at >= updated)
+    return unless emoji.nil? || image_url != emoji.image_remote_url || (updated && updated >= emoji.updated_at)
 
     emoji ||= CustomEmoji.new(domain: @account.domain, shortcode: shortcode, uri: uri)
     emoji.image_remote_url = image_url
diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb
index 3e77579bb..38c578de2 100644
--- a/app/services/fetch_link_card_service.rb
+++ b/app/services/fetch_link_card_service.rb
@@ -136,14 +136,15 @@ class FetchLinkCardService < BaseService
     detector = CharlockHolmes::EncodingDetector.new
     detector.strip_tags = true
 
-    guess = detector.detect(@html, @html_charset)
-    page  = Nokogiri::HTML(@html, nil, guess&.fetch(:encoding, nil))
+    guess      = detector.detect(@html, @html_charset)
+    page       = Nokogiri::HTML(@html, nil, guess&.fetch(:encoding, nil))
+    player_url = meta_property(page, 'twitter:player')
 
-    if meta_property(page, 'twitter:player')
+    if player_url && !bad_url?(Addressable::URI.parse(player_url))
       @card.type   = :video
       @card.width  = meta_property(page, 'twitter:player:width') || 0
       @card.height = meta_property(page, 'twitter:player:height') || 0
-      @card.html   = content_tag(:iframe, nil, src: meta_property(page, 'twitter:player'),
+      @card.html   = content_tag(:iframe, nil, src: player_url,
                                                width: @card.width,
                                                height: @card.height,
                                                allowtransparency: 'true',