From 12535d645b713e69b233bdfce6c049fcd1265cb4 Mon Sep 17 00:00:00 2001 From: Anton Batenev Date: Tue, 17 Dec 2013 01:08:37 +0400 Subject: [PATCH 01/15] Russian translation (actual version) --- config/locales/client.ru.yml | 46 ++++++++++++++++++++++++++++++++---- config/locales/server.ru.yml | 34 +++++++++++++++++++++----- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/config/locales/client.ru.yml b/config/locales/client.ru.yml index ac2cd0f6664..0eedf418233 100644 --- a/config/locales/client.ru.yml +++ b/config/locales/client.ru.yml @@ -197,7 +197,7 @@ ru: you_replied_to_topic: 'Вы ответили в теме' user_mentioned_user: '{{user}} упомянул {{another_user}}' user_mentioned_you: '{{user}} упомянулВас' - you_mentioned_user: 'Вы упомянули{{another_user}}' + you_mentioned_user: 'Вы упомянули {{another_user}}' posted_by_user: 'Размещено пользователем {{user}}' posted_by_you: 'Размещено Вами' sent_by_user: 'Отправлено пользователем {{user}}' @@ -225,6 +225,8 @@ ru: latest_by: 'последние по' toggle_ordering: 'изменить сортировку' subcategories: 'Подкатегории:' + total_topics: 'Всего тем: %{count}' + total_posts: 'Всего сообщений: %{count}' user: said: '{{username}} писал(а):' profile: Профайл @@ -393,12 +395,14 @@ ru: month_desc: 'создано тем за последние 30 дней' week: неделя week_desc: 'создано тем за последние 7 дней' + day: день first_post: 'Первое сообщение' mute: Отключить unmute: Включить summary: enabled_description: 'Вы просматриваете только популярные сообщения в данной теме. Для просмотра всех сообщений нажмите кнопку ниже.' description: 'В теме {{count}} сообщений. Хотите посмотреть только сообщения релевантные теме?' + description_time: 'В теме {{count}} сообщений со средним временем чтения {{readingTime}} минут. Сократить время чтения, отобразив только важные сообщения?' enable: 'Сводка по теме' disable: 'Показать все сообщения' private_message_info: @@ -520,8 +524,10 @@ ru: help: 'Справка по Markdown' toggler: 'скрыть / показать панель редактирования' admin_options_title: 'Дополнительные настройки темы' - auto_close_label: 'Автоматически закрыть тему после:' - auto_close_units: дней + auto_close_label: 'Автоматически закрыть тему:' + auto_close_units: '(# часов, время, или штамп времени)' + auto_close_examples: 'Например: 24, 17:00, 2013-11-22 14:00' + auto_close_error: 'Пожалуйста, введите правильное значение' notifications: title: 'уведомления об упоминании @name в сообщениях, ответах на ваши сообщения и темы, личные сообщения и т.д.' none: 'На данный момент уведомлений нет.' @@ -534,8 +540,8 @@ ru: liked: ' {{username}} {{link}}' private_message: ' {{username}} {{link}}' invited_to_private_message: ' {{username}} {{link}}' - invitee_accepted: ' {{username}} принял ваше приглашение' - moved_post: ' {{username}} переместил сообщение в {{link}}' + invitee_accepted: ' {{username}} принял ваше приглашение' + moved_post: ' {{username}} перемещено {{link}}' total_flagged: 'всего сообщений с жалобами' upload_selector: title: 'Add an image' @@ -653,8 +659,10 @@ ru: title: 'текущее местоположение в теме' jump_top: 'перейти к первому сообщению' jump_bottom: 'перейти к последнему сообщению' + jump_bottom_with_number: 'перейти к сообщению %{post_number}' total: 'всего сообщений' current: 'текущее сообщение' + position: '%{current} сообщение из %{total}' notifications: title: ' ' reasons: @@ -778,6 +786,11 @@ ru: many: '(сообщение отозвано автором и будет автоматически удалено через %{count} часов при отсутствии жалоб)' deleted_by: 'Удалено' expand_collapse: развернуть/свернуть + gap: + one: '1 сообщение пропущено' + other: '{{count}} сообщений пропущено' + few: '{{count}} сообщения пропущено' + many: '{{count}} сообщений пропущено' has_replies: one: ответ other: ответов @@ -949,6 +962,25 @@ ru: other: 'Вы уверены, что хотите удалить эти сообщения?' few: 'Вы уверены, что хотите удалить сообщения?' many: 'Вы уверены, что хотите удалить сообщения?' + revisions: + controls: + first: 'Начальная версия' + previous: 'Предыдущая версия' + next: 'Следующая версия' + last: 'Последняя версия' + comparing_previous_to_current_out_of_total: '#{{previous}} vs. #{{current}} (из {{total}})' + displays: + inline: + title: 'Отобразить сообщение с включенными добавлениями и удалениями.' + button: ' HTML' + side_by_side: + title: 'Отобразить сообщение с построчными изменениями' + button: ' HTML' + side_by_side_markdown: + title: 'Отобразить вывод с построчными изменениями и разметкой' + button: ' Markdown' + details: + edited_by: 'Изменено' category: can: 'может… ' none: '(без категории)' @@ -981,6 +1013,7 @@ ru: already_used: 'Цвет уже используется другой категорией' security: Безопасность auto_close_label: 'Закрыть тему через:' + auto_close_units: часов edit_permissions: 'Изменить права доступа' add_permission: 'Добавить права' this_year: 'в год' @@ -1135,6 +1168,7 @@ ru: disagree_title: 'Удалить все жалобы с данного сообщения' delete_spammer_title: 'Удалить пользователя и все его сообщения.' flagged_by: 'Отмечено' + system: Системные error: 'что-то пошло не так' view_message: Ответить no_results: 'Жалоб нет.' @@ -1430,3 +1464,5 @@ ru: rate_limits: 'Ограничения' developer: Разработчик uncategorized: Без категории + lightbox: + download: загрузить diff --git a/config/locales/server.ru.yml b/config/locales/server.ru.yml index bb4c3c03f15..8e6787cc2d4 100644 --- a/config/locales/server.ru.yml +++ b/config/locales/server.ru.yml @@ -67,6 +67,9 @@ ru: rss_posts_in_topic: 'RSS лента темы ''%{topic}' rss_topics_in_category: 'RSS лента тем в категории ''%{category}''' author_wrote: '%{author} написал:' + num_posts: 'Сообщений:' + num_participants: 'Участников:' + read_full_topic: 'Читать всю тему' private_message_abbrev: ЛС rss_description: latest: 'Последние темы' @@ -85,7 +88,7 @@ ru: trust_level_5: trust_level_5 education: until_posts: - one: сообщение + one: '1 сообщение' other: '%{count} сообщений' few: '%{count} сообщения' many: '%{count} сообщений' @@ -510,7 +513,7 @@ ru: delete_removed_posts_after: 'Количество часов, после которого сообщение, удаленное пользователем, удаляется.' max_image_width: 'Максимальная ширина изображений, добавляемых в сообщение' max_image_height: 'Максимальная высота изображения в сообщении' - category_featured_topics: 'Количество отображаемых тем в категориях на странице /categories' + category_featured_topics: 'Количество тем, отображаемых в одной категории или на странице категорий. После изменения значения требуется около 15 минут для обновления списков.' add_rel_nofollow_to_user_content: 'Добавить "rel nofollow" для всех ссылок за исключением внутренних (включая родительский домен). Изменение данной настройки потребует обновления всех сообщений (rake posts:rebake)' exclude_rel_nofollow_domains: 'Разделенный запятыми список доменов, в которых nofollow не добавлено (tld.com автоматически позволит также и sub.tld.com)' post_excerpt_maxlength: 'Максимальное количество символов выдержки из сообщения' @@ -602,6 +605,7 @@ ru: suggested_topics: 'Количество рекомендованных тем, отображаемых внизу текущей темы' clean_up_uploads: 'Удалить неиспользуемые загрузки для предотвращения хранения нелегального контента. ВНИМАНИЕ: рекомендуется сделать резервную копию директории /uploads перед включением данной настройки.' clean_orphan_uploads_grace_period_hours: 'Период (в часах) после которого неопубликованные вложения удаляются.' + purge_deleted_uploads_grace_period_days: 'Период (в днях) после которого удаленные вложения очищаются.' enable_s3_uploads: 'Размещать загруженные файлы на Amazon S3' s3_upload_bucket: 'Наименование Amazon S3 bucket в который будут загружаться файлы. ВНИМАНИЕ: имя должно быть в нижнем регистре (см. http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html)' s3_access_key_id: 'Amazon S3 access key для загрузки и хранения изображений' @@ -637,7 +641,7 @@ ru: min_title_similar_length: 'Минимальная длина названия темы, при которой тема будет проверена на наличие похожих' min_body_similar_length: 'Минимальная длина тела сообщения, при которой оно будет проверено на наличие похожих тем' category_colors: 'Разделенный чертой (|) список дозволенных hexadecimal цветов для категорий' - enable_wide_category_list: 'Включить традиционный полноразмерный список категорий.' + enable_wide_category_list: 'Использовать обычный полноразмерный список категорий. ВНИМАНИЕ: на текущий момент данная настройка ничего не делает и в скором времени будет удалена. Полноразмерный список является единственно возможным.' max_image_size_kb: 'Максимальный размер изображений для загрузки пользователем в КБ – убедитесь, что вы так же настроили лимит в nginx (client_max_body_size) / apache или прокси.' max_attachment_size_kb: 'Максимальный размер файлов для загрузки пользователем в кб – убедитесь, что вы настроили лимит также в nginx (client_max_body_size) / apache или proxy.' authorized_extensions: 'Список расширений файлов, разрешенных к загрузке, разделенный вертикальной чертой (|)' @@ -675,6 +679,7 @@ ru: enable_names: 'Разрешить пользователям отображать полные имена' display_name_on_posts: 'Отображать полные имена пользователей в сообщениях' invites_shown: 'Максимальное количество приглашений, отображаемых на странице пользователя' + short_progress_text_threshold: 'После достижения указанного числа сообщений в теме, бар будет отображать только текущий номер сообщения. Если вы измените ширину бара, вы можете изменить это значение.' notification_types: mentioned: '%{display_username} упомянул вас в %{link}' liked: '%{display_username} понравилось ваше сообщение в теме %{link}' @@ -711,12 +716,24 @@ ru: archived_disabled: 'Эта тема разархивирована. Она более не заморожена, и может быть изменена.' closed_enabled: 'Эта тема закрыта. В ней больше нельзя отвечать.' closed_disabled: 'Эта тема открыта. В ней можно отвечать.' - autoclosed_enabled: + autoclosed_enabled_days: zero: 'Эта тема была автоматически закрыта через 1 день. В ней больше нельзя отвечать.' one: 'Эта тема была автоматически закрыта через 1 день. В ней больше нельзя отвечать.' - other: 'Эта тема была автоматически закрыта через %{count} дней. В ней больше нельзя отвечать.' + other: 'Эта тема была автоматически закрыта спустя %{count} дней. В ней больше нельзя отвечать.' few: 'Эта тема была автоматически закрыта спустя %{count} дня. В ней больше нельзя отвечать.' many: 'Эта тема была автоматически закрыта спустя %{count} дней. В ней больше нельзя отвечать.' + autoclosed_enabled_hours: + zero: 'Эта тема была автоматически закрыта через 1 час. В ней больше нельзя отвечать.' + one: 'Эта тема была автоматически закрыта через 1 час. В ней больше нельзя отвечать.' + other: 'Эта тема была автоматически закрыта спустя %{count} часов. В ней больше нельзя отвечать.' + few: 'Эта тема была автоматически закрыта спустя %{count} часа. В ней больше нельзя отвечать.' + many: 'Эта тема была автоматически закрыта спустя %{count} часов. В ней больше нельзя отвечать.' + autoclosed_enabled_minutes: + zero: 'Эта тема была автоматически закрыта через 1 минуту. В ней больше нельзя отвечать.' + one: 'Эта тема была автоматически закрыта через 1 минуту. В ней больше нельзя отвечать.' + other: 'Эта тема была автоматически закрыта спустя %{count} минут. В ней больше нельзя отвечать.' + few: 'Эта тема была автоматически закрыта спустя %{count} минуты. В ней больше нельзя отвечать.' + many: 'Эта тема была автоматически закрыта спустя %{count} минут. В ней больше нельзя отвечать.' autoclosed_disabled: 'Эта тема открыта. В ней можно отвечать.' pinned_enabled: 'Эта тема прилеплена. Она будет всегда отображаться первой в списке тем своей категории, пока не будет отлеплена модератором, или сброшена вниз, когда каждый пользователь нажмет кнопку «Отлепить»' pinned_disabled: 'Эта тема отлеплена. Она больше не будет отображаться наверху списка тем категории.' @@ -801,7 +818,7 @@ ru: other: '%{count} пользователей ожидают подтверждения' few: '%{count} пользователя ожидают подтверждения' many: '%{count} пользователей ожидают подтверждения' - text_body_template: "Новые пользователи ожидают подтверждения (или отказа).\n\n[Проверьте список в секции администрирования](/admin/users/list/pending).\n" + text_body_template: "Новые пользователи ожидают подтверждения (или отказа) перед тем, как они получат доступ до форума.\n\n[Проверьте список в секции администрирования](%{base_url}/admin/users/list/pending).\n" unsubscribe_link: 'Для того, чтобы отписаться от подобных сообщений, перейдите в [настройки профиля](%{user_preferences_url}).' user_notifications: previous_discussion: 'Предыдущие ответы' @@ -836,6 +853,11 @@ ru: click_here: 'нажмите здесь' from: 'Cводка новостей сайта %{site_name}' read_more: 'Читать еще' + posts: + one: '1 сообщение' + other: '%{count} сообщений' + few: '%{count} сообщения' + many: '%{count} сообщений' forgot_password: subject_template: '[%{site_name}] Сброс пароля' text_body_template: "Кто-то запросил смену вашего пароля на сайте [%{site_name}](%{base_url}).\n\nЕсли это были не вы, спокойно проигнорируйте это письмо.\n\nПройдите по следующей ссылке, чтобы задать новый пароль:\n%{base_url}/users/password-reset/%{email_token}\n" From 51f92fd87b715f19de02efd2038ee7fc8b8be275 Mon Sep 17 00:00:00 2001 From: ofGEEK Date: Wed, 18 Dec 2013 20:55:09 +0800 Subject: [PATCH 02/15] Update client.zh_CN.yml --- config/locales/client.zh_CN.yml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/config/locales/client.zh_CN.yml b/config/locales/client.zh_CN.yml index d5e753b19bd..710df0a442d 100644 --- a/config/locales/client.zh_CN.yml +++ b/config/locales/client.zh_CN.yml @@ -185,17 +185,26 @@ zh_CN: categories: all: "所有分类" - only_category: "只看{{categoryName}}" + all_subcategories: "所有子分类" + no_subcategory: "无子分类" category: "分类" - posts: "帖子" - topics: "主题" + posts: "新帖子" + topics: "新主题" latest: "最新" latest_by: "最新发表:" toggle_ordering: "排序控制" subcategories: "子分类:" + topic_stats: "新主题的数量。" + topic_stat_sentence: + one: "过去的%{unit}中有%{count}个新主题。" + other: "过去的%{unit}中有%{count}个新主题。" + post_stats: "新帖子的数量。" + post_stat_sentence: + one: "过去的%{unit}中有%{count}个新帖子。" + other: "过去的%{unit}中有%{count}个新帖子。" user: - said: "{{username}} 说:" + said: "{{username}}说:" profile: "个人简介" show_profile: "访问个人简介" mute: "防打扰" @@ -348,6 +357,7 @@ zh_CN: title: "密码" too_short: "你设置的密码太短了。" ok: "你设置的密码符合要求。" + instructions: "至少需要%{count}个字符。" ip_address: title: "最后使用的IP地址" @@ -375,6 +385,7 @@ zh_CN: month_desc: '30天以前发表的主题' week: '周' week_desc: '7天以前发表的主题' + day: '天' first_post: 第一帖 mute: 防打扰 @@ -1003,6 +1014,7 @@ zh_CN: add_permission: "添加权限" this_year: "今年" position: "位置" + default_position: "默认位置" parent: "上级分类" flagging: From 8294dced6c51472390c13786ab4cace4bcf8c7d4 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 18 Dec 2013 11:06:36 -0500 Subject: [PATCH 03/15] tweak RSS elements for W3C compatibility installation needs to have contact_email set in the admin settings in order for that installation to have truly valid feeds --- app/views/list/list.rss.erb | 9 ++++----- app/views/topics/show.rss.erb | 11 +++++------ config/routes.rb | 2 +- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/views/list/list.rss.erb b/app/views/list/list.rss.erb index a9c949c1498..eaf7c608bbb 100644 --- a/app/views/list/list.rss.erb +++ b/app/views/list/list.rss.erb @@ -2,22 +2,21 @@ <% lang = SiteSetting.find_by_name('default_locale').try(:value) %> + <% site_email = SiteSetting.find_by_name('contact_email').try(:value) %> <%= @title %> <%= @link %> <%= @description %> - <% if lang %> - <%= lang %> - <% end %> + <%= "#{lang}" if lang %> <%= @topic_list.topics.first.created_at.rfc2822 %> <% @topic_list.topics.each do |topic| %> <% topic_url = Discourse.base_url + topic.relative_url -%> <%= topic.title %> - <%= "@#{topic.user.username} (#{topic.user.name})" -%> + <%= "#{site_email} (@#{topic.user.username}#{" #{topic.user.name}" if topic.user.name.present?})" -%> <%= topic.category.name %> <%= t('author_wrote', author: link_to(topic.user.name, topic.user)).html_safe %>

+

<%= t('author_wrote', author: link_to(topic.user.name, userpage_url(topic.user))).html_safe %>

<%= topic.posts.first.cooked.html_safe %>
diff --git a/app/views/topics/show.rss.erb b/app/views/topics/show.rss.erb index 85d1e2e5750..61be3b86ada 100644 --- a/app/views/topics/show.rss.erb +++ b/app/views/topics/show.rss.erb @@ -3,23 +3,22 @@ <% topic_url = Discourse.base_url + @topic_view.relative_url %> <% lang = SiteSetting.find_by_name('default_locale').try(:value) %> + <% site_email = SiteSetting.find_by_name('contact_email').try(:value) %> <%= @topic_view.title %> <%= topic_url %> <%= @topic_view.posts.first.raw %> - <% if lang %> - <%= lang %> - <% end %> + <%= "#{lang}" if lang %> <%= @topic_view.topic.created_at.rfc2822 %> <%= @topic_view.topic.category.name %> <% @topic_view.recent_posts.each do |post| %> <% next unless post.user %> - <%= @topic_view.title %> at <%= post.created_at %> - <%= "@#{post.user.username} (#{post.user.name})" -%> + <%= @topic_view.title %> + <%= "#{site_email} (@#{post.user.username}#{" #{post.user.name}" if post.user.name.present?})" -%> -

<%= t('author_wrote', author: link_to(post.user.name, post.user)).html_safe %>

+

<%= t('author_wrote', author: link_to(post.user.name, userpage_url(post.user))).html_safe %>

<%= post.cooked.html_safe %>
diff --git a/config/routes.rb b/config/routes.rb index d91aa179362..36fb3dbcf24 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -140,7 +140,7 @@ Discourse::Application.routes.draw do get 'user_preferences' => 'users#user_preferences_redirect' get 'users/:username/private-messages' => 'user_actions#private_messages', constraints: {username: USERNAME_ROUTE_FORMAT} get 'users/:username/private-messages/:filter' => 'user_actions#private_messages', constraints: {username: USERNAME_ROUTE_FORMAT} - get 'users/:username' => 'users#show', constraints: {username: USERNAME_ROUTE_FORMAT} + get 'users/:username' => 'users#show', as: 'userpage', constraints: {username: USERNAME_ROUTE_FORMAT} put 'users/:username' => 'users#update', constraints: {username: USERNAME_ROUTE_FORMAT} get 'users/:username/preferences' => 'users#preferences', constraints: {username: USERNAME_ROUTE_FORMAT}, as: :email_preferences get 'users/:username/preferences/email' => 'users#preferences', constraints: {username: USERNAME_ROUTE_FORMAT} From 7b2835b73f34808198c69f8edc9504437f09cf48 Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 19 Dec 2013 10:50:15 -0500 Subject: [PATCH 04/15] respect newlines in About Me on profile page --- .../javascripts/discourse/templates/user/user.js.handlebars | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/discourse/templates/user/user.js.handlebars b/app/assets/javascripts/discourse/templates/user/user.js.handlebars index 2181c36a811..7cc6818c731 100644 --- a/app/assets/javascripts/discourse/templates/user/user.js.handlebars +++ b/app/assets/javascripts/discourse/templates/user/user.js.handlebars @@ -41,7 +41,7 @@

{{username}} {{{statusIcon}}}

{{name}}

-
{{{bio_excerpt}}}
+
{{{bio_cooked}}}
{{#if isSuspended}}
From 8dad928557fd52192392143d7a12612ceecb8997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Thu, 19 Dec 2013 17:01:22 +0100 Subject: [PATCH 05/15] Add setupTopicController event --- app/assets/javascripts/discourse/routes/topic_route.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/discourse/routes/topic_route.js b/app/assets/javascripts/discourse/routes/topic_route.js index 5e922405387..8c5b68e0ce5 100644 --- a/app/assets/javascripts/discourse/routes/topic_route.js +++ b/app/assets/javascripts/discourse/routes/topic_route.js @@ -128,10 +128,13 @@ Discourse.TopicRoute = Discourse.Route.extend({ editingTopic: false }); + Discourse.TopicRoute.trigger('setupTopicController', this); + this.controllerFor('header').setProperties({ topic: model, showExtraInfo: false }); + this.controllerFor('composer').set('topic', model); Discourse.TopicTrackingState.current().trackIncoming('all'); controller.subscribe(); @@ -142,4 +145,4 @@ Discourse.TopicRoute = Discourse.Route.extend({ }); - +RSVP.EventTarget.mixin(Discourse.TopicRoute); From c35af5d7557311db9de80ef600bb0148787bb2f5 Mon Sep 17 00:00:00 2001 From: Neil Lalonde Date: Thu, 19 Dec 2013 11:24:21 -0500 Subject: [PATCH 06/15] FIX: When re-opening a topic that auto-closed, make sure it won't auto-close again --- app/models/topic_status_update.rb | 2 +- spec/integration/topic_auto_close_spec.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/models/topic_status_update.rb b/app/models/topic_status_update.rb index f5113b2a93a..e166a46e56b 100644 --- a/app/models/topic_status_update.rb +++ b/app/models/topic_status_update.rb @@ -22,7 +22,7 @@ TopicStatusUpdate = Struct.new(:topic, :user) do topic.update_column status.name, status.enabled? end - if status.manually_closing_topic? && topic.auto_close_at + if topic.auto_close_at && (status.reopening_topic? || status.manually_closing_topic?) topic.reload.set_auto_close(nil).save end diff --git a/spec/integration/topic_auto_close_spec.rb b/spec/integration/topic_auto_close_spec.rb index 9743363924a..7f6c90aaf28 100644 --- a/spec/integration/topic_auto_close_spec.rb +++ b/spec/integration/topic_auto_close_spec.rb @@ -87,6 +87,14 @@ describe Topic do Then { scheduled_jobs_for(:close_topic).should have(2).jobs } end end + + context 'a topic that has been auto-closed' do + Given(:admin) { Fabricate(:admin) } + Given!(:auto_closed_topic) { Fabricate(:topic, user: admin, closed: true, auto_close_at: 1.day.ago, auto_close_user_id: admin.id, auto_close_started_at: 6.days.ago) } + When { auto_closed_topic.update_status('closed', false, admin) } + Then { auto_closed_topic.reload.auto_close_at.should be_nil } + And { auto_closed_topic.auto_close_started_at.should be_nil } + end end end end From 39e711783da73472217bda4574cbb20d90352595 Mon Sep 17 00:00:00 2001 From: Neil Lalonde Date: Thu, 19 Dec 2013 11:45:42 -0500 Subject: [PATCH 07/15] FIX: alignment of avatars and category badge on mobile --- app/assets/stylesheets/mobile/topic-list.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/assets/stylesheets/mobile/topic-list.scss b/app/assets/stylesheets/mobile/topic-list.scss index bd8a687b6e3..b17f9d9472d 100644 --- a/app/assets/stylesheets/mobile/topic-list.scss +++ b/app/assets/stylesheets/mobile/topic-list.scss @@ -163,6 +163,10 @@ // -------------------------------------------------- #topic-list.categories { + .badge-category { + display: inline-block; + margin-top: 1px; + } .featured-users { @include portrait { margin-bottom: 10px; From 1cac9fa257331decc33f53cdff1b43fa9467e27a Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 19 Dec 2013 13:45:55 -0500 Subject: [PATCH 08/15] New users can only post `newuser_max_replies_per_topic` times per topic. --- app/assets/stylesheets/desktop/compose.scss | 6 +++++- app/models/user.rb | 5 +++++ config/locales/server.en.yml | 10 ++++++++++ config/site_settings.yml | 1 + lib/composer_messages_finder.rb | 7 +++++++ lib/validators/post_validator.rb | 7 +++++++ .../composer_messages_finder_spec.rb | 19 +++++++++++++++++++ .../validators/post_validator_spec.rb | 14 ++++++++++++++ 8 files changed, 68 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/desktop/compose.scss b/app/assets/stylesheets/desktop/compose.scss index c4b46c50104..30a63b3fad4 100644 --- a/app/assets/stylesheets/desktop/compose.scss +++ b/app/assets/stylesheets/desktop/compose.scss @@ -18,8 +18,12 @@ @include box-shadow(3px 3px 3px rgba($black, 0.14)); + h3 { + margin-bottom: 10px; + } + p { - margin: 0 0 10px 0; + margin-bottom: 10px; } a.close { diff --git a/app/models/user.rb b/app/models/user.rb index f175dfd03ef..4e4831c3554 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -143,6 +143,7 @@ class User < ActiveRecord::Base where(username_lower: username.downcase).first end + def enqueue_welcome_message(message_type) return unless SiteSetting.send_welcome_message? Jobs.enqueue(:send_system_message, user_id: id, message_type: message_type) @@ -340,6 +341,10 @@ class User < ActiveRecord::Base topics_allowed.where(archetype: Archetype.private_message).count end + def posted_too_much_in_topic?(topic_id) + trust_level == TrustLevel.levels[:newuser] && (Post.where(topic_id: topic_id, user_id: id).count >= SiteSetting.newuser_max_replies_per_topic) + end + def bio_excerpt excerpt = PrettyText.excerpt(bio_cooked, 350) return excerpt if excerpt.blank? || has_trust_level?(:basic) diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index de9d54678a0..1c54ddbf0a2 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -27,6 +27,8 @@ en: site_under_maintenance: 'Site is currently undergoing maintenance.' operation_already_running: "An %{operation} is currently running. Can't start a new %{operation} job right now." + too_many_replies: "Sorry you can't reply any more times in that topic." + too_many_mentions: zero: "Sorry, you can't mention other users." one: "Sorry, you can only mention one other user in a post." @@ -132,6 +134,13 @@ en: Are you sure you're providing adequate time for other people to share their points of view, too? + too_many_replies: | + ### You've replied too many times to this topic + + Sorry, but new users are limited to %{newuser_max_replies_per_topic} replies in a topic. + + You should consider editing one of your previous replies instead of a new reply. + activerecord: attributes: category: @@ -667,6 +676,7 @@ en: newuser_max_images: "How many images a new user can add to a post" newuser_max_attachments: "How many attachments a new user can add to a post" newuser_max_mentions_per_post: "Maximum number of @name notifications a new user can use in a post" + newuser_max_replies_per_topic: "Maximum number of replies a new user can make in a single topic" max_mentions_per_post: "Maximum number of @name notifications you can use in a post" create_thumbnails: "Create thumbnails for lightboxed images" diff --git a/config/site_settings.yml b/config/site_settings.yml index 4b1bbe40cb4..286d6e57526 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -177,6 +177,7 @@ posting: default: true post_undo_action_window_mins: 10 max_mentions_per_post: 10 + newuser_max_replies_per_topic: 3 newuser_max_mentions_per_post: 2 onebox_max_chars: 5000 title_min_entropy: 10 diff --git a/lib/composer_messages_finder.rb b/lib/composer_messages_finder.rb index c39731d820e..c7f27bcba05 100644 --- a/lib/composer_messages_finder.rb +++ b/lib/composer_messages_finder.rb @@ -7,6 +7,7 @@ class ComposerMessagesFinder def find check_education_message || + check_new_user_many_replies || check_avatar_notification || check_sequential_replies || check_dominating_topic @@ -32,6 +33,12 @@ class ComposerMessagesFinder nil end + # New users have a limited number of replies in a topic + def check_new_user_many_replies + return unless replying? && @user.posted_too_much_in_topic?(@details[:topic_id]) + {templateName: 'composer/education', body: PrettyText.cook(I18n.t('education.too_many_replies', newuser_max_replies_per_topic: SiteSetting.newuser_max_replies_per_topic)) } + end + # Should a user be contacted to update their avatar? def check_avatar_notification diff --git a/lib/validators/post_validator.rb b/lib/validators/post_validator.rb index 124d55058ec..5c5dab1efb0 100644 --- a/lib/validators/post_validator.rb +++ b/lib/validators/post_validator.rb @@ -5,6 +5,7 @@ class Validators::PostValidator < ActiveModel::Validator presence(record) stripped_length(record) raw_quality(record) + max_posts_validator(record) max_mention_validator(record) max_images_validator(record) max_attachments_validator(record) @@ -40,6 +41,12 @@ class Validators::PostValidator < ActiveModel::Validator end end + def max_posts_validator(post) + if post.acting_user.present? && post.acting_user.posted_too_much_in_topic?(post.topic_id) + post.errors.add(:base, I18n.t(:too_many_replies)) + end + end + # Ensure new users can not put too many images in a post def max_images_validator(post) add_error_if_count_exceeded(post, :too_many_images, post.image_count, SiteSetting.newuser_max_images) unless acting_user_is_trusted?(post) diff --git a/spec/components/composer_messages_finder_spec.rb b/spec/components/composer_messages_finder_spec.rb index df26e9be682..f211157a1fb 100644 --- a/spec/components/composer_messages_finder_spec.rb +++ b/spec/components/composer_messages_finder_spec.rb @@ -10,6 +10,7 @@ describe ComposerMessagesFinder do it "calls all the message finders" do finder.expects(:check_education_message).once + finder.expects(:check_new_user_many_replies).once finder.expects(:check_avatar_notification).once finder.expects(:check_sequential_replies).once finder.expects(:check_dominating_topic).once @@ -56,6 +57,24 @@ describe ComposerMessagesFinder do finder.check_education_message.should be_blank end end + end + + context '.check_new_user_many_replies' do + let(:user) { Fabricate.build(:user) } + + context 'replying' do + let(:finder) { ComposerMessagesFinder.new(user, composerAction: 'reply') } + + it "has no message when `posted_too_much_in_topic?` is false" do + user.expects(:posted_too_much_in_topic?).returns(false) + finder.check_new_user_many_replies.should be_blank + end + + it "has a message when a user has posted too much" do + user.expects(:posted_too_much_in_topic?).returns(true) + finder.check_new_user_many_replies.should be_present + end + end end diff --git a/spec/components/validators/post_validator_spec.rb b/spec/components/validators/post_validator_spec.rb index 76865503d9e..e1a5ed725ea 100644 --- a/spec/components/validators/post_validator_spec.rb +++ b/spec/components/validators/post_validator_spec.rb @@ -24,6 +24,20 @@ describe Validators::PostValidator do end end + context "too_many_posts" do + it "should be invalid when the user has posted too much" do + post.user.expects(:posted_too_much_in_topic?).returns(true) + validator.max_posts_validator(post) + expect(post.errors.count).to be > 0 + end + + it "should be valid when the user hasn't posted too much" do + post.user.expects(:posted_too_much_in_topic?).returns(false) + validator.max_posts_validator(post) + expect(post.errors.count).to be(0) + end + end + context "invalid post" do it "should be invalid" do validator.validate(post) From 4f7d440fa46f85c187f0572480edd8c674899059 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 19 Dec 2013 14:43:36 -0500 Subject: [PATCH 09/15] Remove unused hook. --- app/assets/javascripts/discourse/dialects/dialect.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/assets/javascripts/discourse/dialects/dialect.js b/app/assets/javascripts/discourse/dialects/dialect.js index ebf09e3d3fb..f7c53f1a66a 100644 --- a/app/assets/javascripts/discourse/dialects/dialect.js +++ b/app/assets/javascripts/discourse/dialects/dialect.js @@ -17,7 +17,6 @@ var parser = window.BetterMarkdown, @method initializeDialects **/ function initializeDialects() { - Discourse.Dialect.trigger('register', {dialect: dialect, MD: MD}); MD.buildBlockOrder(dialect.block); MD.buildInlinePatterns(dialect.inline); initialized = true; From 33c6997ded3f3553f79dca10483a4d3955b6cb85 Mon Sep 17 00:00:00 2001 From: Neil Lalonde Date: Thu, 19 Dec 2013 15:12:03 -0500 Subject: [PATCH 10/15] Move password validation into PasswordValidator --- app/models/user.rb | 18 +++++--- lib/validators/password_validator.rb | 12 +++++ .../validators/password_validator_spec.rb | 46 +++++++++++++++++++ 3 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 lib/validators/password_validator.rb create mode 100644 spec/components/validators/password_validator_spec.rb diff --git a/app/models/user.rb b/app/models/user.rb index 4e4831c3554..44ff39d55e0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -246,11 +246,23 @@ class User < ActiveRecord::Base @raw_password = password unless password.blank? end + def password + '' # so that validator doesn't complain that a password attribute doesn't exist + end + # Indicate that this is NOT a passwordless account for the purposes of validation def password_required! @password_required = true end + def password_required? + !!@password_required + end + + def password_validator + PasswordValidator.new(attributes: :password).validate_each(self, :password, @raw_password) + end + def confirm_password?(password) return false unless password_hash && salt self.password_hash == hash_password(password, salt) @@ -561,12 +573,6 @@ class User < ActiveRecord::Base end end - def password_validator - if (@raw_password && @raw_password.length < 6) || (@password_required && !@raw_password) - errors.add(:password, "must be 6 letters or longer") - end - end - def send_approval_email Jobs.enqueue(:user_email, type: :signup_after_approval, diff --git a/lib/validators/password_validator.rb b/lib/validators/password_validator.rb new file mode 100644 index 00000000000..9f87fdecd68 --- /dev/null +++ b/lib/validators/password_validator.rb @@ -0,0 +1,12 @@ +class PasswordValidator < ActiveModel::EachValidator + + def validate_each(record, attribute, value) + return unless record.password_required? + if value.nil? + record.errors.add(attribute, :blank) + elsif value.length < 6 + record.errors.add(attribute, :too_short, count: 6) + end + end + +end diff --git a/spec/components/validators/password_validator_spec.rb b/spec/components/validators/password_validator_spec.rb new file mode 100644 index 00000000000..cdaa6a38d0e --- /dev/null +++ b/spec/components/validators/password_validator_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe PasswordValidator do + + let(:validator) { described_class.new({attributes: :password}) } + subject(:validate) { validator.validate_each(record,:password,@password) } + + context "password required" do + let(:record) { u = Fabricate.build(:user, password: @password); u.password_required!; u } + + it "doesn't add an error when password is good" do + @password = "weron235alsfn234" + validate + record.errors[:password].should_not be_present + end + + it "adds an error when password is too short" do + @password = "p" + validate + record.errors[:password].should be_present + end + + it "adds an error when password is blank" do + @password = '' + validate + record.errors[:password].should be_present + end + + it "adds an error when password is nil" do + @password = nil + validate + record.errors[:password].should be_present + end + end + + context "password not required" do + let(:record) { Fabricate.build(:user, password: @password) } + + it "doesn't add an error if password is not required" do + @password = nil + validate + record.errors[:password].should_not be_present + end + end + +end From 854d9c8fc6f94f6c3c5bdcd17ab09ce2324411a4 Mon Sep 17 00:00:00 2001 From: Neil Lalonde Date: Thu, 19 Dec 2013 16:15:36 -0500 Subject: [PATCH 11/15] Minimum password length is configurable with the min_password_length site setting. FIX: reset password needs to validate password length. --- .../controllers/create_account_controller.js | 4 +- app/controllers/users_controller.rb | 1 + config/locales/server.en.yml | 1 + config/site_settings.yml | 3 ++ lib/validators/password_validator.rb | 4 +- .../validators/password_validator_spec.rb | 52 ++++++++++++------- .../fixtures/site_settings_fixtures.js | 2 +- 7 files changed, 43 insertions(+), 24 deletions(-) diff --git a/app/assets/javascripts/discourse/controllers/create_account_controller.js b/app/assets/javascripts/discourse/controllers/create_account_controller.js index d409757d621..6babd49d80a 100644 --- a/app/assets/javascripts/discourse/controllers/create_account_controller.js +++ b/app/assets/javascripts/discourse/controllers/create_account_controller.js @@ -31,7 +31,7 @@ Discourse.CreateAccountController = Discourse.Controller.extend(Discourse.ModalF }.property('authOptions.auth_provider'), passwordInstructions: function() { - return I18n.t('user.password.instructions', {count: 6}); // TODO: soon to be configurable + return I18n.t('user.password.instructions', {count: Discourse.SiteSettings.min_password_length}); }.property(), // Validate the name @@ -273,7 +273,7 @@ Discourse.CreateAccountController = Discourse.Controller.extend(Discourse.ModalF } // If too short - if (password.length < 6) { + if (password.length < Discourse.SiteSettings.min_password_length) { return Discourse.InputValidation.create({ failed: true, reason: I18n.t('user.password.too_short') diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 29591269ca0..6174652d2d7 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -172,6 +172,7 @@ class UsersController < ApplicationController elsif request.put? raise Discourse::InvalidParameters.new(:password) unless params[:password].present? @user.password = params[:password] + @user.password_required! logon_after_password_reset if @user.save end render layout: 'no_js' diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 1c54ddbf0a2..da14b65a514 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -603,6 +603,7 @@ en: login_required: "Require authentication to read posts" + min_password_length: "Minimum password length." enable_local_logins: "Enable traditional, local username and password authentication" enable_local_account_create: "Enable creating new local accounts" enable_google_logins: "Enable Google authentication" diff --git a/config/site_settings.yml b/config/site_settings.yml index 286d6e57526..280879454b3 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -76,6 +76,9 @@ users: must_approve_users: client: true default: false + min_password_length: + client: true + default: 8 enable_google_logins: client: true default: true diff --git a/lib/validators/password_validator.rb b/lib/validators/password_validator.rb index 9f87fdecd68..b396cdf3f77 100644 --- a/lib/validators/password_validator.rb +++ b/lib/validators/password_validator.rb @@ -4,8 +4,8 @@ class PasswordValidator < ActiveModel::EachValidator return unless record.password_required? if value.nil? record.errors.add(attribute, :blank) - elsif value.length < 6 - record.errors.add(attribute, :too_short, count: 6) + elsif value.length < SiteSetting.min_password_length + record.errors.add(attribute, :too_short, count: SiteSetting.min_password_length) end end diff --git a/spec/components/validators/password_validator_spec.rb b/spec/components/validators/password_validator_spec.rb index cdaa6a38d0e..6d23ce1be9a 100644 --- a/spec/components/validators/password_validator_spec.rb +++ b/spec/components/validators/password_validator_spec.rb @@ -8,28 +8,42 @@ describe PasswordValidator do context "password required" do let(:record) { u = Fabricate.build(:user, password: @password); u.password_required!; u } - it "doesn't add an error when password is good" do - @password = "weron235alsfn234" - validate - record.errors[:password].should_not be_present + context "min password length is 8" do + before { SiteSetting.stubs(:min_password_length).returns(8) } + + it "doesn't add an error when password is good" do + @password = "weron235alsfn234" + validate + record.errors[:password].should_not be_present + end + + it "adds an error when password is too short" do + @password = "p" + validate + record.errors[:password].should be_present + end + + it "adds an error when password is blank" do + @password = '' + validate + record.errors[:password].should be_present + end + + it "adds an error when password is nil" do + @password = nil + validate + record.errors[:password].should be_present + end end - it "adds an error when password is too short" do - @password = "p" - validate - record.errors[:password].should be_present - end + context "min password length is 12" do + before { SiteSetting.stubs(:min_password_length).returns(12) } - it "adds an error when password is blank" do - @password = '' - validate - record.errors[:password].should be_present - end - - it "adds an error when password is nil" do - @password = nil - validate - record.errors[:password].should be_present + it "adds an error when password length is 11" do + @password = "gt38sdt92bv" + validate + record.errors[:password].should be_present + end end end diff --git a/test/javascripts/fixtures/site_settings_fixtures.js b/test/javascripts/fixtures/site_settings_fixtures.js index 718c65dafb5..d32a26ba707 100644 --- a/test/javascripts/fixtures/site_settings_fixtures.js +++ b/test/javascripts/fixtures/site_settings_fixtures.js @@ -1,3 +1,3 @@ /*jshint maxlen:10000000 */ -Discourse.SiteSettingsOriginal = {"title":"Discourse Meta","logo_url":"/assets/logo.png","logo_small_url":"/assets/logo-single.png","traditional_markdown_linebreaks":false,"top_menu":"latest|new|unread|read|favorited|categories","post_menu":"like|edit|flag|delete|share|bookmark|reply","share_links":"twitter|facebook|google+|email","track_external_right_clicks":false,"must_approve_users":false,"ga_tracking_code":"UA-33736483-2","ga_domain_name":"","enable_long_polling":true,"polling_interval":3000,"anon_polling_interval":30000,"min_post_length":20,"max_post_length":16000,"min_topic_title_length":15,"max_topic_title_length":255,"min_private_message_title_length":2,"allow_uncategorized_topics":true,"min_search_term_length":3,"flush_timings_secs":5,"suppress_reply_directly_below":true,"email_domains_blacklist":"mailinator.com","email_domains_whitelist":null,"version_checks":true,"min_title_similar_length":10,"min_body_similar_length":15,"category_colors":"BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|283890","max_upload_size_kb":1024,"category_featured_topics":6,"favicon_url":"/assets/favicon.ico","dynamic_favicon":false,"uncategorized_name":"uncategorized","uncategorized_color":"AB9364","uncategorized_text_color":"FFFFFF","invite_only":false,"login_required":false,"enable_local_logins":true,"enable_local_account_create":true,"enable_google_logins":true,"enable_yahoo_logins":true,"enable_twitter_logins":true,"enable_facebook_logins":true,"enable_cas_logins":false,"enable_github_logins":true,"enable_persona_logins":true,"educate_until_posts":2,"topic_views_heat_low":1000,"topic_views_heat_medium":2000,"topic_views_heat_high":5000,"min_private_message_post_length":5,"faq_url":"","tos_url":"","privacy_policy_url":"","authorized_extensions":".jpg|.jpeg|.png|.gif|.txt","relative_date_duration":14,"delete_removed_posts_after":24,"delete_user_max_age":7, "default_code_lang": "lang-auto"}; +Discourse.SiteSettingsOriginal = {"title":"Discourse Meta","logo_url":"/assets/logo.png","logo_small_url":"/assets/logo-single.png","traditional_markdown_linebreaks":false,"top_menu":"latest|new|unread|read|favorited|categories","post_menu":"like|edit|flag|delete|share|bookmark|reply","share_links":"twitter|facebook|google+|email","track_external_right_clicks":false,"must_approve_users":false,"ga_tracking_code":"UA-33736483-2","ga_domain_name":"","enable_long_polling":true,"polling_interval":3000,"anon_polling_interval":30000,"min_post_length":20,"max_post_length":16000,"min_topic_title_length":15,"max_topic_title_length":255,"min_private_message_title_length":2,"allow_uncategorized_topics":true,"min_search_term_length":3,"flush_timings_secs":5,"suppress_reply_directly_below":true,"email_domains_blacklist":"mailinator.com","email_domains_whitelist":null,"version_checks":true,"min_title_similar_length":10,"min_body_similar_length":15,"category_colors":"BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|283890","max_upload_size_kb":1024,"category_featured_topics":6,"favicon_url":"/assets/favicon.ico","dynamic_favicon":false,"uncategorized_name":"uncategorized","uncategorized_color":"AB9364","uncategorized_text_color":"FFFFFF","invite_only":false,"login_required":false,"min_password_length":8,"enable_local_logins":true,"enable_local_account_create":true,"enable_google_logins":true,"enable_yahoo_logins":true,"enable_twitter_logins":true,"enable_facebook_logins":true,"enable_cas_logins":false,"enable_github_logins":true,"enable_persona_logins":true,"educate_until_posts":2,"topic_views_heat_low":1000,"topic_views_heat_medium":2000,"topic_views_heat_high":5000,"min_private_message_post_length":5,"faq_url":"","tos_url":"","privacy_policy_url":"","authorized_extensions":".jpg|.jpeg|.png|.gif|.txt","relative_date_duration":14,"delete_removed_posts_after":24,"delete_user_max_age":7, "default_code_lang": "lang-auto"}; Discourse.SiteSettings = jQuery.extend(true, {}, Discourse.SiteSettingsOriginal); From 66616c9574f3d64efe90e669b2f8bfc115fa419c Mon Sep 17 00:00:00 2001 From: Neil Lalonde Date: Thu, 19 Dec 2013 16:51:18 -0500 Subject: [PATCH 12/15] Categories page is even better on Nexus 7 (and probably iPad mini) --- .../stylesheets/common/foundation/mixins.scss | 16 +++------- app/assets/stylesheets/mobile/topic-list.scss | 31 +++++++++++++++---- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/app/assets/stylesheets/common/foundation/mixins.scss b/app/assets/stylesheets/common/foundation/mixins.scss index 54cdef40066..c075e15e3df 100644 --- a/app/assets/stylesheets/common/foundation/mixins.scss +++ b/app/assets/stylesheets/common/foundation/mixins.scss @@ -41,17 +41,11 @@ } } -@mixin portrait { - @media only screen and (max-width : 320px) { - @content; - } -} - -@mixin landscape { - @media only screen and (min-width : 321px) { - @content; - } -} +@mixin mobile-portrait { @media only screen and (max-width : 320px) { @content; } } +@mixin not-mobile-portrait { @media only screen and (min-width : 321px) { @content; } } +@mixin mobile-landscape { @media only screen and (min-width : 321px) and (max-width : 959px) { @content; } } +@mixin not-tablet-landscape { @media only screen and (max-width : 959px) { @content; } } +@mixin tablet-landscape { @media only screen and (min-width : 960px) { @content; } } // CSS3 properties // -------------------------------------------------- diff --git a/app/assets/stylesheets/mobile/topic-list.scss b/app/assets/stylesheets/mobile/topic-list.scss index b17f9d9472d..7229d221be9 100644 --- a/app/assets/stylesheets/mobile/topic-list.scss +++ b/app/assets/stylesheets/mobile/topic-list.scss @@ -50,7 +50,7 @@ border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; - tbody tr { + > tbody > tr { background-color: $white; &:nth-child(even) { background-color: darken($white, 4%); @@ -167,19 +167,23 @@ display: inline-block; margin-top: 1px; } + .category-description { + margin-top: 8px; + } .featured-users { - @include portrait { + @include mobile-portrait { margin-bottom: 10px; padding-top: 8px; clear: left; } - @include landscape { + @include not-mobile-portrait { float: right; } } .latest { - @include portrait { width: 150px; } - @include landscape { width: 270px; } + @include mobile-portrait { width: 150px; } + @include mobile-landscape { width: 270px; } + @include tablet-landscape { width: 450px; } .featured-topic { margin: 8px 0; a.last-posted-at, a.last-posted-at:visited { @@ -188,7 +192,22 @@ } } .stats { - display: none; + @include not-tablet-landscape { display: none; } + @include tablet-landscape { min-width: 80px; } + } + td.stats { + .unit { + font-size: 11px; + } + } + table.categoryStats { + td { + padding: 2px; + vertical-align: bottom; + line-height: 17px; + &.value { text-align: right; } + &.unit { text-align: left; } + } } } From 452232096f3672907053766dda383936b90d1040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Fri, 20 Dec 2013 00:32:39 +0100 Subject: [PATCH 13/15] smaller images in oneboxes --- app/assets/stylesheets/desktop/onebox.scss | 17 +++++++---------- app/assets/stylesheets/mobile/onebox.scss | 15 ++++++--------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/app/assets/stylesheets/desktop/onebox.scss b/app/assets/stylesheets/desktop/onebox.scss index 74498136eff..55a6544684e 100644 --- a/app/assets/stylesheets/desktop/onebox.scss +++ b/app/assets/stylesheets/desktop/onebox.scss @@ -16,7 +16,7 @@ a.loading-onebox { .onebox-result { margin-top: 15px; - padding: 12px 25px 12px 12px; + padding: 12px 25px 12px 12px; border-left: 5px solid #bebebe; background: #eee; font-size: 14px; @@ -43,7 +43,10 @@ a.loading-onebox { .onebox-result-body { padding-top: 5px; img { - max-width:200px; + max-width: 100px; + max-height: 80%; + float: left; + margin-right: 10px; } h3, h4 { margin: 0px !important; @@ -55,12 +58,6 @@ a.loading-onebox { code { max-height: 400px; } - img { - max-width: 30%; - max-height: 80%; - float: left; - margin-right: 10px; - } .metrics { clear: both; padding-bottom: 25px; @@ -76,8 +73,8 @@ a.loading-onebox { // RottenTomatoes Onebox .onebox-result { .onebox-result-body { - img.verdict { - float: none; + img.verdict { + float: none; margin-right: 7px; } img.popcorn { diff --git a/app/assets/stylesheets/mobile/onebox.scss b/app/assets/stylesheets/mobile/onebox.scss index a0fb25e1e5e..f0a31864357 100644 --- a/app/assets/stylesheets/mobile/onebox.scss +++ b/app/assets/stylesheets/mobile/onebox.scss @@ -39,7 +39,10 @@ a.loading-onebox { padding-top: 5px; font-family: Georgia, Times, "Times New Roman", serif; img { - max-width:200px; + max-width: 100px; + max-height: 80%; + float: left; + margin-right: 10px; } h3, h4 { margin: 0px !important; @@ -51,12 +54,6 @@ a.loading-onebox { code { max-height: 400px; } - img { - max-width: 30%; - max-height: 80%; - float: left; - margin-right: 10px; - } .metrics { clear: both; padding-bottom: 25px; @@ -72,8 +69,8 @@ a.loading-onebox { // RottenTomatoes Onebox .onebox-result { .onebox-result-body { - img.verdict { - float: none; + img.verdict { + float: none; margin-right: 7px; } img.popcorn { From e6e04ca0e948348424159315dd9fb8652eb4d2c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Fri, 20 Dec 2013 00:58:48 +0100 Subject: [PATCH 14/15] FIX: new user username color --- app/assets/stylesheets/desktop/poster_expansion.scss | 8 ++++---- app/assets/stylesheets/desktop/topic-post.scss | 4 ++++ app/assets/stylesheets/mobile/topic-post.scss | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/desktop/poster_expansion.scss b/app/assets/stylesheets/desktop/poster_expansion.scss index 36d239e8fa7..20d650c0875 100644 --- a/app/assets/stylesheets/desktop/poster_expansion.scss +++ b/app/assets/stylesheets/desktop/poster_expansion.scss @@ -13,10 +13,6 @@ padding: 12px 12px 5px 12px; max-width: 350px; - h1.new-user a { - color: $dark_gray; - } - h1 { font-size: 30px; line-height: 33px; @@ -67,4 +63,8 @@ .btn { margin: 0 0 7px 0; } + + .new-user a { + color: $dark_gray; + } } diff --git a/app/assets/stylesheets/desktop/topic-post.scss b/app/assets/stylesheets/desktop/topic-post.scss index 5550ffa3d59..506e8153681 100644 --- a/app/assets/stylesheets/desktop/topic-post.scss +++ b/app/assets/stylesheets/desktop/topic-post.scss @@ -572,6 +572,10 @@ iframe { font-size: 36px; } +.new-user a { + color: $dark_gray; +} + .staff a { padding: 4px; margin: -4px 0 0 0; diff --git a/app/assets/stylesheets/mobile/topic-post.scss b/app/assets/stylesheets/mobile/topic-post.scss index 936590ffff2..a834af759c8 100644 --- a/app/assets/stylesheets/mobile/topic-post.scss +++ b/app/assets/stylesheets/mobile/topic-post.scss @@ -433,7 +433,7 @@ iframe { background-color: lighten(yellow, 35%); } -h3.new-user a[href] { +.new-user a { color: $dark_gray; } From 2ac9ad6d517e1443954b5b1473d9d5f4ac63046b Mon Sep 17 00:00:00 2001 From: Jeff Atwood Date: Thu, 19 Dec 2013 16:05:12 -0800 Subject: [PATCH 15/15] edit copy on new user topic reply limit --- config/locales/server.en.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index da14b65a514..97350bcf521 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -135,11 +135,11 @@ en: Are you sure you're providing adequate time for other people to share their points of view, too? too_many_replies: | - ### You've replied too many times to this topic + ### You have reached the reply limit - Sorry, but new users are limited to %{newuser_max_replies_per_topic} replies in a topic. + We're sorry, but new users are temporarily limited to %{newuser_max_replies_per_topic} replies in a single topic. - You should consider editing one of your previous replies instead of a new reply. + Instead of adding another reply, please consider editing your previous replies. activerecord: attributes: