app/controllers & decorators i18n (#16126)
* app/controllers (& decorators) i18n etc * tidy key names * update keys * delete ja.yml * delete an involved ja.yml * fix for PR review * fix for spec * delete ja.yml
This commit is contained in:
parent
aa7b8d9f62
commit
c4778d832e
52 changed files with 424 additions and 157 deletions
|
|
@ -9,7 +9,7 @@ class ApiSecretsController < ApplicationController
|
|||
@secret.user_id = current_user.id
|
||||
|
||||
if @secret.save
|
||||
flash[:notice] = "Your API Key has been generated: #{@secret.secret}"
|
||||
flash[:notice] = I18n.t("api_secrets_controller.generated", secret: @secret.secret)
|
||||
else
|
||||
flash[:error] = @secret.errors_as_sentence
|
||||
end
|
||||
|
|
@ -21,10 +21,10 @@ class ApiSecretsController < ApplicationController
|
|||
authorize @secret
|
||||
|
||||
if @secret.destroy
|
||||
flash[:notice] = "Your API Key has been revoked."
|
||||
flash[:notice] = I18n.t("api_secrets_controller.revoked")
|
||||
else
|
||||
flash[:error] =
|
||||
"An error occurred. Please try again or send an email to: #{ForemInstance.email}"
|
||||
I18n.t("errors.messages.try_again_email", email: ForemInstance.email)
|
||||
end
|
||||
|
||||
redirect_back(fallback_location: root_path)
|
||||
|
|
|
|||
|
|
@ -73,12 +73,12 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def not_authorized
|
||||
render json: { error: "Error: not authorized" }, status: :unauthorized
|
||||
render json: { error: I18n.t("application_controller.not_authorized") }, status: :unauthorized
|
||||
raise NotAuthorizedError, "Unauthorized"
|
||||
end
|
||||
|
||||
def bad_request
|
||||
render json: { error: "Error: Bad Request" }, status: :bad_request
|
||||
render json: { error: I18n.t("application_controller.bad_request") }, status: :bad_request
|
||||
end
|
||||
|
||||
def error_too_many_requests(exc)
|
||||
|
|
@ -94,7 +94,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to sign_up_path }
|
||||
format.json { render json: { error: "Please sign in" }, status: :unauthorized }
|
||||
format.json { render json: { error: I18n.t("application_controller.please_sign_in") }, status: :unauthorized }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,6 @@ class ArticleApprovalsController < ApplicationController
|
|||
end
|
||||
end
|
||||
@article.update(approved: params[:approved])
|
||||
redirect_to "#{URI.parse(@article.path).path}/mod"
|
||||
redirect_to "#{Addressable::URI.parse(@article.path).path}/mod"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ class ArticlesController < ApplicationController
|
|||
return
|
||||
end
|
||||
if params[:destination]
|
||||
redirect_to(URI.parse(params[:destination]).path)
|
||||
redirect_to(Addressable::URI.parse(params[:destination]).path)
|
||||
return
|
||||
end
|
||||
if params[:article][:video_thumbnail_url]
|
||||
|
|
@ -159,7 +159,7 @@ class ArticlesController < ApplicationController
|
|||
authorize @article
|
||||
Articles::Destroyer.call(@article)
|
||||
respond_to do |format|
|
||||
format.html { redirect_to "/dashboard", notice: "Article was successfully deleted." }
|
||||
format.html { redirect_to "/dashboard", notice: I18n.t("articles_controller.deleted") }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class CommentsController < ApplicationController
|
|||
|
||||
if @comment.invalid?
|
||||
@comment.destroy
|
||||
render json: { error: "comment already exists" }, status: :unprocessable_entity
|
||||
render json: { error: I18n.t("comments_controller.create.failure") }, status: :unprocessable_entity
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ class CommentsController < ApplicationController
|
|||
)[1])
|
||||
|
||||
comment.destroy
|
||||
render json: { error: "comment already exists" }, status: :unprocessable_entity
|
||||
render json: { error: I18n.t("comments_controller.create.failure") }, status: :unprocessable_entity
|
||||
else
|
||||
message = @comment.errors_as_sentence
|
||||
render json: { error: message }, status: :unprocessable_entity
|
||||
|
|
@ -91,7 +91,7 @@ class CommentsController < ApplicationController
|
|||
rescue StandardError => e
|
||||
skip_authorization
|
||||
|
||||
message = "There was an error in your markdown: #{e}"
|
||||
message = I18n.t("comments_controller.markdown", error: e)
|
||||
render json: { error: message }, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
|
|
@ -106,26 +106,23 @@ class CommentsController < ApplicationController
|
|||
@comment.user_id = moderator.id
|
||||
@comment.body_markdown = response_template.content
|
||||
authorize @comment
|
||||
permit_commenter
|
||||
|
||||
if @comment.save
|
||||
Notification.send_new_comment_notifications_without_delay(@comment)
|
||||
Mention.create_all(@comment)
|
||||
|
||||
render json: { status: "created", path: @comment.path }
|
||||
render json: { status: I18n.t("comments_controller.create.success"), path: @comment.path }
|
||||
elsif (@comment = Comment.where(body_markdown: @comment.body_markdown,
|
||||
commentable_id: @comment.commentable.id,
|
||||
ancestry: @comment.ancestry)[0])
|
||||
render json: { status: "comment already exists" }, status: :conflict
|
||||
render json: { status: I18n.t("comments_controller.create.failure") }, status: :conflict
|
||||
else
|
||||
render json: { status: @comment&.errors&.full_messages&.to_sentence }, status: :unprocessable_entity
|
||||
end
|
||||
rescue ModerationUnauthorizedError => e
|
||||
render json: { error: e.message }, status: :unprocessable_entity
|
||||
rescue StandardError => e
|
||||
skip_authorization
|
||||
|
||||
message = "There was an error in your markdown: #{e}"
|
||||
message = I18n.t("comments_controller.markdown", error: e)
|
||||
render json: { error: "error", status: message }, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
|
|
@ -169,7 +166,7 @@ class CommentsController < ApplicationController
|
|||
end
|
||||
rescue StandardError => e
|
||||
@commentable = @comment.commentable
|
||||
flash.now[:error] = "There was an error in your markdown: #{e}"
|
||||
flash.now[:error] = I18n.t("comments_controller.markdown", error: e)
|
||||
render :edit
|
||||
end
|
||||
|
||||
|
|
@ -186,7 +183,7 @@ class CommentsController < ApplicationController
|
|||
redirect = @comment.commentable&.path || user_path(current_user)
|
||||
# NOTE: Brakeman doesn't like redirecting to a path, because of a "possible
|
||||
# unprotected redirect". Using URI.parse().path is the recommended workaround.
|
||||
redirect_to URI.parse(redirect).path, notice: "Comment was successfully deleted."
|
||||
redirect_to Addressable::URI.parse(redirect).path, notice: I18n.t("comments_controller.delete.notice")
|
||||
end
|
||||
|
||||
def delete_confirm
|
||||
|
|
@ -202,7 +199,7 @@ class CommentsController < ApplicationController
|
|||
parsed_markdown = MarkdownProcessor::Parser.new(fixed_body_markdown, source: Comment.new, user: current_user)
|
||||
processed_html = parsed_markdown.finalize
|
||||
rescue StandardError => e
|
||||
processed_html = "<p>😔 There was an error in your markdown</p><hr><p>#{e}</p>"
|
||||
processed_html = I18n.t("comments_controller.markdown_html", error: e)
|
||||
end
|
||||
respond_to do |format|
|
||||
format.json { render json: { processed_html: processed_html }, status: :ok }
|
||||
|
|
@ -262,8 +259,8 @@ class CommentsController < ApplicationController
|
|||
if @comment.save
|
||||
redirect_url = @comment.commentable&.path
|
||||
if redirect_url
|
||||
flash[:success] = "Comment was successfully deleted."
|
||||
redirect_to URI.parse(redirect_url).path
|
||||
flash[:success] = I18n.t("comments_controller.delete.notice")
|
||||
redirect_to Addressable::URI.parse(redirect_url).path
|
||||
else
|
||||
redirect_to_comment_path
|
||||
end
|
||||
|
|
@ -300,7 +297,7 @@ class CommentsController < ApplicationController
|
|||
end
|
||||
|
||||
def redirect_to_comment_path
|
||||
flash[:error] = "Something went wrong; Comment NOT deleted."
|
||||
flash[:error] = I18n.t("comments_controller.delete.error")
|
||||
redirect_to "#{@comment.path}/mod"
|
||||
end
|
||||
|
||||
|
|
@ -315,7 +312,7 @@ class CommentsController < ApplicationController
|
|||
def permit_commenter
|
||||
return unless user_blocked?
|
||||
|
||||
raise ModerationUnauthorizedError, "Not allowed due to moderation action"
|
||||
raise ModerationUnauthorizedError, I18n.t("comments_controller.moderated")
|
||||
end
|
||||
|
||||
def user_blocked?
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ module ImageUploads
|
|||
extend ActiveSupport::Concern
|
||||
|
||||
MAX_FILENAME_LENGTH = 250
|
||||
FILENAME_TOO_LONG_MESSAGE = "filename too long - the max is #{MAX_FILENAME_LENGTH} characters.".freeze
|
||||
IS_NOT_FILE_MESSAGE = "invalid file type. Please upload a valid image.".freeze
|
||||
|
||||
def long_filename?(image)
|
||||
image&.original_filename && image.original_filename.length > MAX_FILENAME_LENGTH
|
||||
|
|
@ -13,4 +11,12 @@ module ImageUploads
|
|||
def file?(image)
|
||||
image.respond_to?(:original_filename)
|
||||
end
|
||||
|
||||
def filename_too_long_message
|
||||
I18n.t("concerns.image_uploads.too_long", max: MAX_FILENAME_LENGTH)
|
||||
end
|
||||
|
||||
def is_not_file_message # rubocop:disable Naming/PredicateName
|
||||
I18n.t("concerns.image_uploads.is_not_file")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
class ConfirmationsController < Devise::ConfirmationsController
|
||||
FLASH_MESSAGE = "Email sent! Please contact support at %<email>s if you are "\
|
||||
"having trouble receiving your confirmation instructions.".freeze
|
||||
|
||||
# GET /resource/confirmation?confirmation_token=abcdef
|
||||
def show
|
||||
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
|
||||
|
|
@ -24,7 +21,7 @@ class ConfirmationsController < Devise::ConfirmationsController
|
|||
self.resource = resource_class.send_confirmation_instructions(resource_params)
|
||||
resource.errors.clear # Don't leak user information, like paranoid mode.
|
||||
|
||||
message = format(FLASH_MESSAGE, email: ForemInstance.email)
|
||||
message = I18n.t("confirmations_controller.email_sent", email: ForemInstance.email)
|
||||
flash.now[:global_notice] = message
|
||||
render :new
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class CreditsController < ApplicationController
|
|||
|
||||
if payment.success?
|
||||
@purchaser = payment.purchaser
|
||||
redirect_to credits_path, notice: "#{number_to_purchase} new credits purchased!"
|
||||
redirect_to credits_path, notice: I18n.t("credits_controller.done", count: number_to_purchase)
|
||||
else
|
||||
flash[:error] = payment.error
|
||||
redirect_to purchase_credits_path
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class DevicesController < ApplicationController
|
|||
def destroy
|
||||
device = Device.find_by(unauthenticated_params)
|
||||
unless device
|
||||
render json: { error: "Not Found", status: 404 }, status: :not_found
|
||||
render json: { error: I18n.t("devices_controller.not_found"), status: 404 }, status: :not_found
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ class DiscussionLocksController < ApplicationController
|
|||
if @discussion_lock.save
|
||||
bust_article_cache(article)
|
||||
|
||||
flash[:success] = "Discussion was successfully locked!"
|
||||
flash[:success] = I18n.t("discussion_locks_controller.locked")
|
||||
else
|
||||
flash[:error] = "Error: #{@discussion_lock.errors_as_sentence}"
|
||||
flash[:error] = I18n.t("errors.messages.general", errors: @discussion_lock.errors_as_sentence)
|
||||
end
|
||||
|
||||
redirect_to "#{article.path}/manage"
|
||||
|
|
@ -30,9 +30,9 @@ class DiscussionLocksController < ApplicationController
|
|||
if discussion_lock.destroy
|
||||
bust_article_cache(article)
|
||||
|
||||
flash[:success] = "Discussion was successfully unlocked!"
|
||||
flash[:success] = I18n.t("discussion_locks_controller.unlocked")
|
||||
else
|
||||
flash[:error] = "Error: #{discussion_lock.errors_as_sentence}"
|
||||
flash[:error] = I18n.t("errors.messages.general", errors: @discussion_lock.errors_as_sentence)
|
||||
end
|
||||
|
||||
redirect_to "#{article.path}/manage"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ class EmailSubscriptionsController < ApplicationController
|
|||
if verified_params[:expires_at] > Time.current
|
||||
user = User.find(verified_params[:user_id])
|
||||
user.notification_setting.update(verified_params[:email_type] => false)
|
||||
@email_type = preferred_email_name.fetch(verified_params[:email_type], "this list")
|
||||
@email_type = preferred_email_name.fetch(verified_params[:email_type],
|
||||
I18n.t("email_subscriptions_controller.this_list")).call
|
||||
else
|
||||
render "invalid_token"
|
||||
end
|
||||
|
|
@ -15,12 +16,15 @@ class EmailSubscriptionsController < ApplicationController
|
|||
|
||||
def preferred_email_name
|
||||
{
|
||||
email_digest_periodic: "#{Settings::Community.community_name} digest emails",
|
||||
email_comment_notifications: "comment notifications",
|
||||
email_follower_notifications: "follower notifications",
|
||||
email_mention_notifications: "mention notifications",
|
||||
email_unread_notifications: "unread notifications",
|
||||
email_badge_notifications: "badge notifications"
|
||||
email_digest_periodic: lambda {
|
||||
I18n.t("email_subscriptions_controller.digest_emails",
|
||||
community: Settings::Community.community_name)
|
||||
},
|
||||
email_comment_notifications: -> { I18n.t("email_subscriptions_controller.comment_notifications") },
|
||||
email_follower_notifications: -> { I18n.t("email_subscriptions_controller.follower_notifications") },
|
||||
email_mention_notifications: -> { I18n.t("email_subscriptions_controller.mention_notifications") },
|
||||
email_unread_notifications: -> { I18n.t("email_subscriptions_controller.unread_notifications") },
|
||||
email_badge_notifications: -> { I18n.t("email_subscriptions_controller.badge_notifications") }
|
||||
}.freeze
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
class FeedbackMessagesController < ApplicationController
|
||||
# No authorization required for entirely public controller
|
||||
skip_before_action :verify_authenticity_token
|
||||
FLASH_MESSAGE = "Make sure the forms are filled. 🤖 Other possible errors: "\
|
||||
"%<errors>s".freeze
|
||||
FEEDBACK_ALLOWED_PARAMS = %i[message feedback_type category reported_url offender_id].freeze
|
||||
|
||||
def create
|
||||
|
|
@ -31,11 +29,15 @@ class FeedbackMessagesController < ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to feedback_messages_path }
|
||||
format.json { render json: { success: true, message: "Your report is submitted" } }
|
||||
format.json do
|
||||
render json: { success: true, message: I18n.t("feedback_messages_controller.submitted") }
|
||||
end
|
||||
end
|
||||
else
|
||||
@previous_message = feedback_message_params[:message]
|
||||
flash[:notice] = format(FLASH_MESSAGE, errors: @feedback_message.errors_as_sentence.presence || "N/A")
|
||||
flash[:notice] =
|
||||
I18n.t("feedback_messages_controller.error_fill",
|
||||
errors: @feedback_message.errors_as_sentence.presence || I18n.t("feedback_messages_controller.n_a"))
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render "pages/report_abuse" }
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ class FollowsController < ApplicationController
|
|||
unfollow(followable, params[:followable_type], need_notification: need_notification)
|
||||
else
|
||||
if rate_limiter.limit_by_action("follow_account")
|
||||
render json: { error: "Daily account follow limit reached!" }, status: :too_many_requests
|
||||
render json: { error: I18n.t("follows_controller.daily_limit") },
|
||||
status: :too_many_requests
|
||||
return
|
||||
end
|
||||
follow(followable, need_notification: need_notification)
|
||||
|
|
@ -101,10 +102,10 @@ class FollowsController < ApplicationController
|
|||
def follow(followable, need_notification: false)
|
||||
user_follow = current_user.follow(followable)
|
||||
Notification.send_new_follower_notification(user_follow) if need_notification
|
||||
"followed"
|
||||
I18n.t("follows_controller.followed")
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
ForemStatsClient.increment("users.invalid_follow")
|
||||
"already followed"
|
||||
I18n.t("follows_controller.already_followed")
|
||||
end
|
||||
|
||||
def unfollow(followable, followable_type, need_notification: false)
|
||||
|
|
@ -113,6 +114,6 @@ class FollowsController < ApplicationController
|
|||
|
||||
Follows::DeleteCached.call(current_user, followable_type, followable.id)
|
||||
|
||||
"unfollowed"
|
||||
I18n.t("follows_controller.unfollowed")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ class GithubReposController < ApplicationController
|
|||
# to fetch all of the user's repositories. This could eventually become slow
|
||||
@repos = fetch_repositories_from_github(known_repositories)
|
||||
rescue Github::Errors::Unauthorized => e
|
||||
render json: { error: "GitHub Unauthorized: #{e.message}", status: 401 }, status: :unauthorized
|
||||
render json: { error: I18n.t("github_repos_controller.github_unauthorized", e_message: e.message), status: 401 },
|
||||
status: :unauthorized
|
||||
end
|
||||
|
||||
def update_or_create
|
||||
|
|
@ -20,7 +21,8 @@ class GithubReposController < ApplicationController
|
|||
|
||||
fetched_repo = fetch_repository_from_github(repo_params[:github_id_code])
|
||||
unless fetched_repo
|
||||
render json: { error: "GitHub repository not found", status: 404 }, status: :not_found
|
||||
render json: { error: I18n.t("github_repos_controller.repo_not_found"), status: 404 },
|
||||
status: :not_found
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ class ImageUploadsController < ApplicationController
|
|||
rescue CarrierWave::ProcessingError # server error
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: { error: "A server error has occurred!" }, status: :unprocessable_entity
|
||||
render json: { error: I18n.t("image_uploads_controller.server_error") },
|
||||
status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
return
|
||||
|
|
@ -49,8 +50,8 @@ class ImageUploadsController < ApplicationController
|
|||
def validate_image
|
||||
images = Array.wrap(params["image"])
|
||||
return if images.blank?
|
||||
return IS_NOT_FILE_MESSAGE unless valid_image_files?(images)
|
||||
return FILENAME_TOO_LONG_MESSAGE unless valid_filenames?(images)
|
||||
return is_not_file_message unless valid_image_files?(images)
|
||||
return filename_too_long_message unless valid_filenames?(images)
|
||||
|
||||
nil
|
||||
end
|
||||
|
|
|
|||
|
|
@ -92,13 +92,13 @@ class ListingsController < ApplicationController
|
|||
def destroy
|
||||
authorize @listing
|
||||
@listing.destroy!
|
||||
redirect_to "/listings/dashboard", notice: "Listing was successfully deleted."
|
||||
redirect_to "/listings/dashboard", notice: I18n.t("listings_controller.deleted")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def process_no_credit_left
|
||||
redirect_to credits_path, notice: "Not enough available credits"
|
||||
redirect_to credits_path, notice: I18n.t("listings_controller.no_credit")
|
||||
end
|
||||
|
||||
def process_successful_draft
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
rescue StandardError => e
|
||||
Honeybadger.notify(e)
|
||||
|
||||
flash[:alert] = "Log in error: #{e}"
|
||||
flash[:alert] = I18n.t("omniauth_callbacks_controller.log_in_error", e: e)
|
||||
redirect_to new_user_registration_url
|
||||
end
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
end
|
||||
|
||||
def user_persisted_but_username_taken?
|
||||
@user.persisted? && @user.errors_as_sentence.include?("username has already been taken")
|
||||
@user.persisted? && @user.errors_as_sentence.include?(I18n.t("omniauth_callbacks_controller.username_taken"))
|
||||
end
|
||||
|
||||
# We only bypass CSRF checks on Apple callback path & Apple trusted ORIGIN
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class OrganizationsController < ApplicationController
|
|||
rate_limiter.track_limit_by_action(:organization_creation)
|
||||
@organization_membership = OrganizationMembership.create!(organization_id: @organization.id,
|
||||
user_id: current_user.id, type_of_user: "admin")
|
||||
flash[:settings_notice] = "Your organization was successfully created and you are an admin."
|
||||
flash[:settings_notice] = I18n.t("organizations_controller.created")
|
||||
redirect_to "/settings/organization/#{@organization.id}"
|
||||
else
|
||||
render template: "users/edit"
|
||||
|
|
@ -62,7 +62,7 @@ class OrganizationsController < ApplicationController
|
|||
|
||||
if @organization.update(organization_params.merge(profile_updated_at: Time.current))
|
||||
@organization.users.touch_all(:organization_info_updated_at)
|
||||
flash[:settings_notice] = "Your organization was successfully updated."
|
||||
flash[:settings_notice] = I18n.t("organizations_controller.updated")
|
||||
redirect_to "/settings/organization"
|
||||
else
|
||||
@org_organization_memberships = @organization.organization_memberships.includes(:user)
|
||||
|
|
@ -79,12 +79,11 @@ class OrganizationsController < ApplicationController
|
|||
|
||||
Organizations::DeleteWorker.perform_async(organization.id, current_user.id)
|
||||
flash[:settings_notice] =
|
||||
"Your organization: \"#{organization.name}\" deletion is scheduled. You'll be notified when it's deleted."
|
||||
I18n.t("organizations_controller.deletion_scheduled", organization_name: organization.name)
|
||||
|
||||
redirect_to user_settings_path(:organization)
|
||||
rescue Pundit::NotAuthorizedError
|
||||
flash[:error] = "Your organization was not deleted; you must be an admin, the only member in the organization, " \
|
||||
"and have no articles connected to the organization."
|
||||
flash[:error] = I18n.t("organizations_controller.not_deleted")
|
||||
redirect_to user_settings_path(:organization, id: organization.id)
|
||||
end
|
||||
|
||||
|
|
@ -92,7 +91,7 @@ class OrganizationsController < ApplicationController
|
|||
set_organization
|
||||
@organization.secret = @organization.generated_random_secret
|
||||
@organization.save
|
||||
flash[:settings_notice] = "Your org secret was updated"
|
||||
flash[:settings_notice] = I18n.t("organizations_controller.secret_updated")
|
||||
redirect_to user_settings_path(:organization)
|
||||
end
|
||||
|
||||
|
|
@ -137,7 +136,7 @@ class OrganizationsController < ApplicationController
|
|||
def valid_image_file?(image)
|
||||
return true if file?(image)
|
||||
|
||||
@organization.errors.add(:profile_image, IS_NOT_FILE_MESSAGE)
|
||||
@organization.errors.add(:profile_image, is_not_file_message)
|
||||
|
||||
false
|
||||
end
|
||||
|
|
@ -145,7 +144,7 @@ class OrganizationsController < ApplicationController
|
|||
def valid_filename?(image)
|
||||
return true unless long_filename?(image)
|
||||
|
||||
@organization.errors.add(:profile_image, FILENAME_TOO_LONG_MESSAGE)
|
||||
@organization.errors.add(:profile_image, filename_too_long_message)
|
||||
|
||||
false
|
||||
end
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ class PagesController < ApplicationController
|
|||
|
||||
def redirect_daily_thread_request(daily_thread)
|
||||
if daily_thread
|
||||
redirect_to(URI.parse(daily_thread.path).path)
|
||||
redirect_to(Addressable::URI.parse(daily_thread.path).path)
|
||||
else
|
||||
redirect_to(notifications_path)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class PodcastsController < ApplicationController
|
|||
|
||||
if @podcast.save
|
||||
current_user.add_role(:podcast_admin, @podcast) if added_by_owner?
|
||||
flash[:global_notice] = "Podcast suggested"
|
||||
flash[:global_notice] = I18n.t("podcasts_controller.podcast_suggested")
|
||||
|
||||
redirect_to pod_path
|
||||
else
|
||||
|
|
@ -74,10 +74,10 @@ class PodcastsController < ApplicationController
|
|||
|
||||
def valid_image_files_and_names?(images)
|
||||
images.each do |field, image|
|
||||
@podcast.errors.add(field, IS_NOT_FILE_MESSAGE) unless file?(image)
|
||||
@podcast.errors.add(field, is_not_file_message) unless file?(image)
|
||||
break if @podcast.errors.any?
|
||||
|
||||
@podcast.errors.add(field, FILENAME_TOO_LONG_MESSAGE) if long_filename?(image)
|
||||
@podcast.errors.add(field, filename_too_long_message) if long_filename?(image)
|
||||
end
|
||||
|
||||
@podcast.errors.blank?
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ class ProfilePinsController < ApplicationController
|
|||
@profile_pin.pinnable_id = profile_pin_params[:pinnable_id].to_i
|
||||
@profile_pin.pinnable_type = "Article"
|
||||
if @profile_pin.save
|
||||
flash[:success] = "📌 Pinned! (pinned posts display chronologically, 5 max)"
|
||||
flash[:success] = I18n.t("views.pins.pinned")
|
||||
else
|
||||
flash[:error] = "You can only have five pins"
|
||||
flash[:error] = I18n.t("views.pins.error")
|
||||
end
|
||||
redirect_back(fallback_location: "/dashboard")
|
||||
bust_user_profile
|
||||
|
|
@ -20,7 +20,7 @@ class ProfilePinsController < ApplicationController
|
|||
# for removing pinnable
|
||||
current_user.profile_pins.destroy_by(id: params[:id])
|
||||
bust_user_profile
|
||||
flash[:pins_success] = "🗑 Pin removed"
|
||||
flash[:success] = I18n.t("views.pins.removed")
|
||||
redirect_back(fallback_location: "/dashboard")
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ class ProfilesController < ApplicationController
|
|||
def update
|
||||
update_result = Users::Update.call(current_user, update_params)
|
||||
if update_result.success?
|
||||
flash[:settings_notice] = "Your profile has been updated"
|
||||
flash[:settings_notice] = I18n.t("profiles_controller.updated")
|
||||
redirect_to user_settings_path
|
||||
else
|
||||
@user = current_user
|
||||
@tab = "profile"
|
||||
flash[:error] = "Error: #{update_result.errors_as_sentence}"
|
||||
flash[:error] = I18n.t("errors.messages.general", errors: update_result.errors_as_sentence)
|
||||
render template: "users/edit", locals: {
|
||||
user: update_params[:user],
|
||||
profile: update_params[:profile],
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class RatingVotesController < ApplicationController
|
|||
format.json do
|
||||
render json: { error: rating_vote.errors.full_messages.to_sentence }, status: :unprocessable_entity
|
||||
end
|
||||
format.html { render json: { result: "Not Upserted Successfully" } }
|
||||
format.html { render json: { result: I18n.t("rating_votes_controller.not_upserted_successfully") } }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
authorize(params, policy_class: RegistrationPolicy)
|
||||
|
||||
unless recaptcha_verified?
|
||||
flash[:notice] = "You must complete the recaptcha ✅"
|
||||
flash[:notice] = I18n.t("registrations_controller.error.recaptcha")
|
||||
return redirect_to new_user_registration_path(state: "email_signup")
|
||||
end
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
# Alright, this error message isn't quite correct. Is the email
|
||||
# from a blocked domain? Or an explicitly allowed domain. I
|
||||
# think this is enough.
|
||||
resource.errors.add(:email, "is not included in allowed domains.")
|
||||
resource.errors.add(:email, I18n.t("registrations_controller.error.domain"))
|
||||
end
|
||||
|
||||
def build_devise_resource
|
||||
|
|
|
|||
|
|
@ -32,10 +32,12 @@ class ResponseTemplatesController < ApplicationController
|
|||
response_template.type_of = "personal_comment"
|
||||
|
||||
if response_template.save
|
||||
flash[:settings_notice] = "Your response template \"#{response_template.title}\" was created."
|
||||
flash[:settings_notice] =
|
||||
I18n.t("response_templates_controller.created", title: response_template.title)
|
||||
redirect_to user_settings_path(tab: "response-templates", id: response_template.id)
|
||||
else
|
||||
flash[:error] = "Response template error: #{response_template.errors_as_sentence}"
|
||||
flash[:error] =
|
||||
I18n.t("response_templates_controller.response_template_error", errors: response_template.errors_as_sentence)
|
||||
attributes = permitted_attributes(ResponseTemplate)
|
||||
redirect_to user_settings_path(
|
||||
tab: "response-templates",
|
||||
|
|
@ -50,7 +52,8 @@ class ResponseTemplatesController < ApplicationController
|
|||
authorize response_template
|
||||
|
||||
if response_template.destroy
|
||||
flash[:settings_notice] = "Your response template \"#{response_template.title}\" was deleted."
|
||||
flash[:settings_notice] =
|
||||
I18n.t("response_templates_controller.deleted", title: response_template.title)
|
||||
else
|
||||
flash[:error] = response_template.errors_as_sentence # this will probably never fail
|
||||
end
|
||||
|
|
@ -63,10 +66,12 @@ class ResponseTemplatesController < ApplicationController
|
|||
|
||||
attributes = permitted_attributes(ResponseTemplate)
|
||||
if response_template.update(attributes)
|
||||
flash[:settings_notice] = "Your response template \"#{response_template.title}\" was updated."
|
||||
flash[:settings_notice] =
|
||||
I18n.t("response_templates_controller.updated", title: response_template.title)
|
||||
redirect_to user_settings_path(tab: "response-templates", id: response_template.id)
|
||||
else
|
||||
flash[:error] = "Response template error: #{response_template.errors_as_sentence}"
|
||||
flash[:error] =
|
||||
I18n.t("response_templates_controller.response_template_error", errors: response_template.errors_as_sentence)
|
||||
redirect_to user_settings_path(
|
||||
tab: "response-templates",
|
||||
id: response_template.id,
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class SocialPreviewsController < ApplicationController
|
|||
format.png do
|
||||
html = render_to_string(template, formats: :html, layout: false)
|
||||
redirect_to HtmlCssToImage.fetch_url(html: html, css: PNG_CSS,
|
||||
google_fonts: "Roboto|Roboto+Condensed"), status: :found
|
||||
google_fonts: I18n.t("social_previews_controller.fonts")), status: :found
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ module Stories
|
|||
rescue_from ArgumentError, with: :bad_request
|
||||
|
||||
def index
|
||||
@query = "...searching"
|
||||
@query = I18n.t("stories_controller.searching")
|
||||
@article_index = true
|
||||
@current_ordering = current_search_results_ordering
|
||||
set_surrogate_key_header "articles-page-with-query"
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ module Stories
|
|||
pinned_at: PinnedArticle.updated_at.iso8601
|
||||
}
|
||||
else
|
||||
render json: { error: "not found" }, status: :not_found
|
||||
render json: { error: I18n.t("stories.pinned_articles_controller.not_found") }, status: :not_found
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ class StoriesController < ApplicationController
|
|||
potential_username = params[:username].tr("@", "").downcase
|
||||
@user = User.find_by("old_username = ? OR old_old_username = ?", potential_username, potential_username)
|
||||
if @user&.articles&.find_by(slug: params[:slug])
|
||||
redirect_permanently_to(URI.parse("/#{@user.username}/#{params[:slug]}").path)
|
||||
redirect_permanently_to(Addressable::URI.parse("/#{@user.username}/#{params[:slug]}").path)
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -401,7 +401,7 @@ class StoriesController < ApplicationController
|
|||
url: URL.organization(@organization),
|
||||
image: @organization.profile_image_url_for(length: 320),
|
||||
name: @organization.name,
|
||||
description: @organization.summary.presence || "404 bio not found"
|
||||
description: @organization.summary.presence || I18n.t("stories_controller.404_bio_not_found")
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ class StripeActiveCardsController < ApplicationController
|
|||
customer = find_or_create_customer
|
||||
|
||||
if Payments::Customer.create_source(customer.id, stripe_params[:stripe_token])
|
||||
flash[:settings_notice] = "Your billing information has been updated"
|
||||
flash[:settings_notice] = I18n.t("stripe_active_cards_controller.updated")
|
||||
audit_log("add")
|
||||
else
|
||||
ForemStatsClient.increment("stripe.errors", tags: ["action:create_card", "user_id:#{current_user.id}"])
|
||||
|
||||
flash[:error] = "There was a problem updating your billing info."
|
||||
flash[:error] = I18n.t("stripe_active_cards_controller.cannot_update")
|
||||
end
|
||||
redirect_to user_settings_path(:billing)
|
||||
rescue Payments::CardError, Payments::InvalidRequestError => e
|
||||
|
|
@ -35,11 +35,11 @@ class StripeActiveCardsController < ApplicationController
|
|||
customer.default_source = card.id
|
||||
|
||||
if Payments::Customer.save(customer)
|
||||
flash[:settings_notice] = "Your billing information has been updated"
|
||||
flash[:settings_notice] = I18n.t("stripe_active_cards_controller.updated")
|
||||
audit_log("update")
|
||||
else
|
||||
ForemStatsClient.increment("stripe.errors", tags: ["action:update_card", "user_id:#{current_user.id}"])
|
||||
flash[:error] = "There was a problem updating your billing info."
|
||||
flash[:error] = I18n.t("stripe_active_cards_controller.cannot_update")
|
||||
end
|
||||
|
||||
redirect_to user_settings_path(:billing)
|
||||
|
|
@ -55,13 +55,13 @@ class StripeActiveCardsController < ApplicationController
|
|||
customer = find_customer
|
||||
|
||||
if customer.subscriptions.count.positive?
|
||||
flash[:error] = "Can't remove card if you have an active membership. Please cancel your membership first."
|
||||
flash[:error] = I18n.t("stripe_active_cards_controller.cannot_remove")
|
||||
else
|
||||
source = Payments::Customer.get_source(customer, params[:id])
|
||||
Payments::Customer.detach_source(customer.id, source.id)
|
||||
Payments::Customer.save(customer)
|
||||
|
||||
flash[:settings_notice] = "Your card has been successfully removed."
|
||||
flash[:settings_notice] = I18n.t("stripe_active_cards_controller.removed")
|
||||
audit_log("remove")
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class TagAdjustmentsController < ApplicationController
|
|||
render json: { status: "Success", result: tag_adjustment.adjustment_type,
|
||||
colors: { bg: tag.bg_color_hex, text: tag.text_color_hex } }
|
||||
end
|
||||
format.html { redirect_to "#{URI.parse(article.path).path}/mod" }
|
||||
format.html { redirect_to "#{Addressable::URI.parse(article.path).path}/mod" }
|
||||
end
|
||||
else
|
||||
# TODO: remove this when we move over to full JSON endpoint
|
||||
|
|
@ -35,7 +35,10 @@ class TagAdjustmentsController < ApplicationController
|
|||
@already_adjusted_tags = @adjustments.map(&:tag_name).join(", ")
|
||||
@allowed_to_adjust = @moderatable.instance_of?(Article) && (current_user.any_admin? || @tag_moderator_tags.any?)
|
||||
respond_to do |format|
|
||||
format.json { render json: { error: "Failure: #{tag_adjustment.errors.full_messages.to_sentence}" } }
|
||||
format.json do
|
||||
render json: { error: I18n.t("tag_adjustments_controller.failure",
|
||||
errors: tag_adjustment.errors.full_messages.to_sentence) }
|
||||
end
|
||||
format.html { render template: "moderations/mod" }
|
||||
end
|
||||
end
|
||||
|
|
@ -57,8 +60,8 @@ class TagAdjustmentsController < ApplicationController
|
|||
|
||||
respond_to do |format|
|
||||
# TODO: add tag adjustment removal async route in actions panel
|
||||
format.json { render json: { result: "Tag adjustment destroyed" } }
|
||||
format.html { redirect_to "#{URI.parse(@article.path).path}/mod" }
|
||||
format.json { render json: { result: I18n.t("tag_adjustments_controller.destroyed") } }
|
||||
format.html { redirect_to "#{Addressable::URI.parse(@article.path).path}/mod" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class TagsController < ApplicationController
|
|||
@tag = Tag.find(params[:id])
|
||||
authorize @tag
|
||||
if @tag.errors.messages.blank? && @tag.update(tag_params)
|
||||
flash[:success] = "Tag successfully updated! 👍 "
|
||||
flash[:success] = I18n.t("tags_controller.tag_successfully_updated")
|
||||
redirect_to "#{URL.tag_path(@tag)}/edit"
|
||||
else
|
||||
flash[:error] = @tag.errors.full_messages
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ module Users
|
|||
cookies.permanent[:user_experience_level] = users_setting.experience_level.to_s
|
||||
end
|
||||
current_user.touch(:profile_updated_at)
|
||||
flash[:settings_notice] = "Your config has been updated. Refresh to see all changes."
|
||||
flash[:settings_notice] = I18n.t("users_controller.updated_config")
|
||||
else
|
||||
Honeycomb.add_field("error", users_setting.errors.messages.compact_blank)
|
||||
Honeycomb.add_field("errored", true)
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ class UsersController < ApplicationController
|
|||
ALLOWED_ONBOARDING_PARAMS = %i[checked_code_of_conduct checked_terms_and_conditions].freeze
|
||||
INDEX_ATTRIBUTES_FOR_SERIALIZATION = %i[id name username summary profile_image].freeze
|
||||
private_constant :INDEX_ATTRIBUTES_FOR_SERIALIZATION
|
||||
REMOVE_IDENTITY_ERROR = "An error occurred. Please try again or send an email to: %<email>s".freeze
|
||||
private_constant :REMOVE_IDENTITY_ERROR
|
||||
|
||||
def index
|
||||
@users =
|
||||
|
|
@ -51,9 +49,9 @@ class UsersController < ApplicationController
|
|||
# explicitly requested "Feed fetch now" or simply updated any other field
|
||||
import_articles_from_feed(@user)
|
||||
|
||||
notice = "Your profile was successfully updated."
|
||||
notice = I18n.t("users_controller.updated_profile")
|
||||
if @user.export_requested?
|
||||
notice += " The export will be emailed to you shortly."
|
||||
notice += I18n.t("users_controller.send_export")
|
||||
ExportContentWorker.perform_async(@user.id, @user.email)
|
||||
end
|
||||
if @user.setting.experience_level.present?
|
||||
|
|
@ -79,16 +77,16 @@ class UsersController < ApplicationController
|
|||
set_current_tab("account")
|
||||
|
||||
if destroy_request_in_progress?
|
||||
notice = "You have already requested account deletion. Please, check your email for further instructions."
|
||||
notice = I18n.t("users_controller.deletion_in_progress")
|
||||
flash[:settings_notice] = notice
|
||||
redirect_to user_settings_path(@tab)
|
||||
elsif @user.email?
|
||||
Users::RequestDestroy.call(@user)
|
||||
notice = "You have requested account deletion. Please, check your email for further instructions."
|
||||
notice = I18n.t("users_controller.deletion_requested")
|
||||
flash[:settings_notice] = notice
|
||||
redirect_to user_settings_path(@tab)
|
||||
else
|
||||
flash[:settings_notice] = "Please, provide an email to delete your account."
|
||||
flash[:settings_notice] = I18n.t("users_controller.provide_email")
|
||||
redirect_to user_settings_path("account")
|
||||
end
|
||||
end
|
||||
|
|
@ -99,15 +97,14 @@ class UsersController < ApplicationController
|
|||
if @user
|
||||
authorize @user
|
||||
else
|
||||
flash[:alert] = "You must be logged in to proceed with account deletion."
|
||||
flash[:alert] = I18n.t("users_controller.log_in_to_delete")
|
||||
redirect_to sign_up_path and return
|
||||
end
|
||||
|
||||
destroy_token = Rails.cache.read("user-destroy-token-#{@user.id}")
|
||||
|
||||
# rubocop:disable Layout/LineLength
|
||||
if destroy_token.blank?
|
||||
flash[:settings_notice] = "Your token has expired, please request a new one. Tokens only last for 12 hours after account deletion is initiated."
|
||||
flash[:settings_notice] = I18n.t("users_controller.token_expired")
|
||||
redirect_to user_settings_path("account")
|
||||
elsif destroy_token != params[:token]
|
||||
Honeycomb.add_field("destroy_token", destroy_token)
|
||||
|
|
@ -115,7 +112,6 @@ class UsersController < ApplicationController
|
|||
|
||||
raise ActionController::RoutingError, "Not Found"
|
||||
end
|
||||
# rubocop:enable Layout/LineLength
|
||||
end
|
||||
|
||||
def full_delete
|
||||
|
|
@ -123,10 +119,10 @@ class UsersController < ApplicationController
|
|||
if @user.email?
|
||||
Users::DeleteWorker.perform_async(@user.id)
|
||||
sign_out @user
|
||||
flash[:global_notice] = "Your account deletion is scheduled. You'll be notified when it's deleted."
|
||||
flash[:global_notice] = I18n.t("users_controller.deletion_scheduled")
|
||||
redirect_to new_user_registration_path
|
||||
else
|
||||
flash[:settings_notice] = "Please, provide an email to delete your account"
|
||||
flash[:settings_notice] = I18n.t("users_controller.provide_email_delete")
|
||||
redirect_to user_settings_path("account")
|
||||
end
|
||||
end
|
||||
|
|
@ -134,7 +130,7 @@ class UsersController < ApplicationController
|
|||
def remove_identity
|
||||
set_current_tab("account")
|
||||
|
||||
error_message = format(REMOVE_IDENTITY_ERROR, email: ForemInstance.email)
|
||||
error_message = I18n.t("errors.messages.try_again_email", email: ForemInstance.email)
|
||||
unless Authentication::Providers.enabled?(params[:provider])
|
||||
flash[:error] = error_message
|
||||
redirect_to user_settings_path(@tab)
|
||||
|
|
@ -158,7 +154,8 @@ class UsersController < ApplicationController
|
|||
# We should delete them when a user unlinks their GitHub account.
|
||||
@user.github_repos.destroy_all if provider.provider_name == :github
|
||||
|
||||
flash[:settings_notice] = "Your #{provider.official_name} account was successfully removed."
|
||||
flash[:settings_notice] =
|
||||
I18n.t("users_controller.removed_identity", provider: provider.official_name)
|
||||
else
|
||||
flash[:error] = error_message
|
||||
end
|
||||
|
|
@ -173,7 +170,7 @@ class UsersController < ApplicationController
|
|||
|
||||
if params[:user]
|
||||
if params[:user].key?(:username) && params[:user][:username].blank?
|
||||
return render_update_response(false, "Username cannot be blank")
|
||||
return render_update_response(false, I18n.t("users_controller.username_blank"))
|
||||
end
|
||||
|
||||
sanitize_user_params
|
||||
|
|
@ -198,10 +195,11 @@ class UsersController < ApplicationController
|
|||
authorize User
|
||||
if (@organization = Organization.find_by(secret: params[:org_secret].strip))
|
||||
OrganizationMembership.create(user_id: current_user.id, organization_id: @organization.id, type_of_user: "member")
|
||||
flash[:settings_notice] = "You have joined the #{@organization.name} organization."
|
||||
flash[:settings_notice] =
|
||||
I18n.t("users_controller.joined_org", organization_name: @organization.name)
|
||||
redirect_to "/settings/organization/#{@organization.id}"
|
||||
else
|
||||
flash[:error] = "The given organization secret was invalid."
|
||||
flash[:error] = I18n.t("users_controller.invalid_secret")
|
||||
redirect_to "/settings/organization/new"
|
||||
end
|
||||
end
|
||||
|
|
@ -210,7 +208,7 @@ class UsersController < ApplicationController
|
|||
org = Organization.find_by(id: params[:organization_id])
|
||||
authorize org
|
||||
OrganizationMembership.find_by(organization_id: org.id, user_id: current_user.id)&.delete
|
||||
flash[:settings_notice] = "You have left your organization."
|
||||
flash[:settings_notice] = I18n.t("users_controller.left_org")
|
||||
redirect_to "/settings/organization/new"
|
||||
end
|
||||
|
||||
|
|
@ -222,7 +220,7 @@ class UsersController < ApplicationController
|
|||
organization: org)
|
||||
|
||||
OrganizationMembership.find_by(user_id: adminable.id, organization_id: org.id).update(type_of_user: "admin")
|
||||
flash[:settings_notice] = "#{adminable.name} is now an admin."
|
||||
flash[:settings_notice] = I18n.t("users_controller.added_admin", name: adminable.name)
|
||||
redirect_to "/settings/organization/#{org.id}"
|
||||
end
|
||||
|
||||
|
|
@ -233,7 +231,7 @@ class UsersController < ApplicationController
|
|||
not_authorized unless current_user.org_admin?(org) && unadminable.org_admin?(org)
|
||||
|
||||
OrganizationMembership.find_by(user_id: unadminable.id, organization_id: org.id).update(type_of_user: "member")
|
||||
flash[:settings_notice] = "#{unadminable.name} is no longer an admin."
|
||||
flash[:settings_notice] = I18n.t("users_controller.removed_admin", name: unadminable.name)
|
||||
redirect_to "/settings/organization/#{org.id}"
|
||||
end
|
||||
|
||||
|
|
@ -245,7 +243,7 @@ class UsersController < ApplicationController
|
|||
not_authorized unless current_user.org_admin?(org) && removable_org_membership
|
||||
|
||||
removable_org_membership.delete
|
||||
flash[:settings_notice] = "#{removable.name} is no longer part of your organization."
|
||||
flash[:settings_notice] = I18n.t("users_controller.removed_member", name: removable.name)
|
||||
redirect_to "/settings/organization/#{org.id}"
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ class VideoStatesController < ApplicationController
|
|||
|
||||
NotifyMailer.with(article: @article).video_upload_complete_email.deliver_now
|
||||
|
||||
render json: { message: "Video state updated" }
|
||||
render json: { message: I18n.t("video_states_controller.video_state_updated") }
|
||||
else
|
||||
render json: { message: "Related article not found" }, status: :not_found
|
||||
render json: { message: I18n.t("video_states_controller.related_article_not_found") }, status: :not_found
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class ArticleDecorator < ApplicationDecorator
|
|||
modified_description += "." unless description.end_with?(".")
|
||||
return modified_description if cached_tag_list.blank?
|
||||
|
||||
modified_description + " Tagged with #{cached_tag_list}."
|
||||
modified_description + I18n.t("decorators.article_decorator.tagged_with", cached_tag_list: cached_tag_list)
|
||||
end
|
||||
|
||||
def video_metadata
|
||||
|
|
@ -102,8 +102,7 @@ class ArticleDecorator < ApplicationDecorator
|
|||
|
||||
# Used in determining when to bust additional routes for an Article's comments
|
||||
def discussion?
|
||||
cached_tag_list_array.include?("discuss") &&
|
||||
featured_number.to_i > 35.hours.ago.to_i
|
||||
cached_tag_list_array.include?("discuss") && featured_number.to_i > 35.hours.ago.to_i
|
||||
end
|
||||
|
||||
def pinned?
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ class CommentDecorator < ApplicationDecorator
|
|||
|
||||
def readable_publish_date
|
||||
if created_at.year == Time.current.year
|
||||
created_at.strftime("%b %-e")
|
||||
I18n.l(created_at, format: :short)
|
||||
else
|
||||
created_at.strftime("%b %-e '%y")
|
||||
I18n.l(created_at, format: :short_with_yy)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ class PodcastEpisodeDecorator < ApplicationDecorator
|
|||
return "" unless published_at
|
||||
|
||||
if published_at.year == Time.current.year
|
||||
published_at.strftime("%b %-e")
|
||||
I18n.l(published_at, format: :short)
|
||||
else
|
||||
published_at.strftime("%b %-e '%y")
|
||||
I18n.l(published_at, format: :short_with_yy)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class UserDecorator < ApplicationDecorator
|
|||
},
|
||||
].freeze
|
||||
|
||||
DEFAULT_PROFILE_SUMMARY = "404 bio not found".freeze
|
||||
DEFAULT_PROFILE_SUMMARY = -> { I18n.t("stories_controller.404_bio_not_found") }
|
||||
|
||||
# The relevant attribute names for cached tags. These are the attributes that we'll make
|
||||
# available in the front-end. The list comes from the two places (see below for that list).
|
||||
|
|
@ -132,7 +132,7 @@ class UserDecorator < ApplicationDecorator
|
|||
|
||||
# Returns the users profile summary or a placeholder text
|
||||
def profile_summary
|
||||
profile.summary.presence || DEFAULT_PROFILE_SUMMARY
|
||||
profile.summary.presence || DEFAULT_PROFILE_SUMMARY.call
|
||||
end
|
||||
|
||||
delegate :display_sponsors, to: :setting
|
||||
|
|
|
|||
|
|
@ -93,14 +93,14 @@ module Users
|
|||
def valid_image_file?(image)
|
||||
return true if file?(image)
|
||||
|
||||
errors.append(IS_NOT_FILE_MESSAGE)
|
||||
errors.append(is_not_file_message)
|
||||
false
|
||||
end
|
||||
|
||||
def valid_filename?(image)
|
||||
return true unless long_filename?(image)
|
||||
|
||||
errors.append(FILENAME_TOO_LONG_MESSAGE)
|
||||
errors.append(filename_too_long_message)
|
||||
false
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@
|
|||
<div id="page-content" class="wrapper <%= view_class %>" data-current-page="<%= current_page %>">
|
||||
<% if flash[:global_notice] %>
|
||||
<div class="crayons-banner" id="setup-banner" aria-live="polite">
|
||||
<%= flash[:global_notice] %>
|
||||
<%== flash[:global_notice] %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div id="page-content-inner">
|
||||
|
|
|
|||
6
config/locales/concerns/en.yml
Normal file
6
config/locales/concerns/en.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
en:
|
||||
concerns:
|
||||
image_uploads:
|
||||
too_long: filename too long - the max is %{max} characters.
|
||||
is_not_file: invalid file type. Please upload a valid image.
|
||||
6
config/locales/concerns/fr.yml
Normal file
6
config/locales/concerns/fr.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
fr:
|
||||
concerns:
|
||||
image_uploads:
|
||||
too_long: filename too long - the max is %{max} characters.
|
||||
is_not_file: invalid file type. Please upload a valid image.
|
||||
121
config/locales/controllers/en.yml
Normal file
121
config/locales/controllers/en.yml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
---
|
||||
en:
|
||||
api_secrets_controller:
|
||||
generated: 'Your API Key has been generated: %{secret}'
|
||||
revoked: Your API Key has been revoked.
|
||||
application_controller:
|
||||
bad_request: 'Error: Bad Request'
|
||||
not_authorized: 'Error: not authorized'
|
||||
please_sign_in: Please sign in
|
||||
articles_controller:
|
||||
deleted: Article was successfully deleted.
|
||||
comments_controller:
|
||||
create:
|
||||
success: created
|
||||
failure: comment already exists
|
||||
delete:
|
||||
error: Something went wrong; Comment NOT deleted.
|
||||
notice: Comment was successfully deleted.
|
||||
markdown: 'There was an error in your markdown: %{error}'
|
||||
markdown_html: "<p>😔 There was an error in your markdown</p><hr><p>%{error}</p>"
|
||||
moderated: Not allowed due to moderation action
|
||||
confirmations_controller:
|
||||
email_sent: Email sent! Please contact support at %{email} if you are having trouble receiving your confirmation instructions.
|
||||
credits_controller:
|
||||
done:
|
||||
one: "%{count} new credits purchased!"
|
||||
other: "%{count} new credits purchased!"
|
||||
devices_controller:
|
||||
not_found: Not Found
|
||||
discussion_locks_controller:
|
||||
locked: Discussion was successfully locked!
|
||||
unlocked: Discussion was successfully unlocked!
|
||||
email_subscriptions_controller:
|
||||
badge_notifications: badge notifications
|
||||
comment_notifications: comment notifications
|
||||
digest_emails: "%{community} digest emails"
|
||||
follower_notifications: follower notifications
|
||||
mention_notifications: mention notifications
|
||||
this_list: this list
|
||||
unread_notifications: unread notifications
|
||||
feedback_messages_controller:
|
||||
error_fill: "Make sure the forms are filled. 🤖 Other possible errors: %{errors}"
|
||||
n_a: N/A
|
||||
submitted: Your report is submitted
|
||||
follows_controller:
|
||||
already_followed: already followed
|
||||
daily_limit: Daily account follow limit reached!
|
||||
followed: followed
|
||||
unfollowed: unfollowed
|
||||
github_repos_controller:
|
||||
repo_not_found: GitHub repository not found
|
||||
github_unauthorized: 'GitHub Unauthorized: %{e_message}'
|
||||
image_uploads_controller:
|
||||
server_error: A server error has occurred!
|
||||
listings_controller:
|
||||
deleted: Listing was successfully deleted.
|
||||
no_credit: Not enough available credits
|
||||
omniauth_callbacks_controller:
|
||||
log_in_error: 'Log in error: %{e}'
|
||||
username_taken: username has already been taken
|
||||
organizations_controller:
|
||||
secret_updated: Your org secret was updated
|
||||
deletion_scheduled: 'Your organization: "%{organization_name}" deletion is scheduled. You''ll be notified when it''s deleted.'
|
||||
not_deleted: Your organization was not deleted; you must be an admin, the only member in the organization, and have no articles connected to the organization.
|
||||
created: Your organization was successfully created and you are an admin.
|
||||
updated: Your organization was successfully updated.
|
||||
podcasts_controller:
|
||||
podcast_suggested: Podcast suggested
|
||||
profiles_controller:
|
||||
updated: Your profile has been updated
|
||||
rating_votes_controller:
|
||||
not_upserted_successfully: Not Upserted Successfully
|
||||
registrations_controller:
|
||||
error:
|
||||
recaptcha: You must complete the recaptcha ✅
|
||||
domain: is not included in allowed domains.
|
||||
response_templates_controller:
|
||||
response_template_error: 'Response template error: %{errors}'
|
||||
created: Your response template "%{title}" was created.
|
||||
deleted: Your response template "%{title}" was deleted.
|
||||
updated: Your response template "%{title}" was updated.
|
||||
social_previews_controller:
|
||||
fonts: Roboto|Roboto+Condensed
|
||||
stories:
|
||||
pinned_articles_controller:
|
||||
not_found: not found
|
||||
stories_controller:
|
||||
404_bio_not_found: 404 bio not found
|
||||
searching: "...searching"
|
||||
stripe_active_cards_controller:
|
||||
cannot_remove: Can't remove card if you have an active membership. Please cancel your membership first.
|
||||
cannot_update: There was a problem updating your billing info.
|
||||
updated: Your billing information has been updated
|
||||
removed: Your card has been successfully removed.
|
||||
tag_adjustments_controller:
|
||||
failure: 'Failure: %{errors}'
|
||||
destroyed: Tag adjustment destroyed
|
||||
tags_controller:
|
||||
tag_successfully_updated: "Tag successfully updated! 👍 "
|
||||
users_controller:
|
||||
removed_admin: "%{name} is no longer an admin."
|
||||
removed_member: "%{name} is no longer part of your organization."
|
||||
added_admin: "%{name} is now an admin."
|
||||
provide_email: Please, provide an email to delete your account.
|
||||
provide_email_delete: Please, provide an email to delete your account
|
||||
send_export: " The export will be emailed to you shortly."
|
||||
invalid_secret: The given organization secret was invalid.
|
||||
username_blank: Username cannot be blank
|
||||
deletion_in_progress: You have already requested account deletion. Please, check your email for further instructions.
|
||||
joined_org: You have joined the %{organization_name} organization.
|
||||
left_org: You have left your organization.
|
||||
deletion_requested: You have requested account deletion. Please, check your email for further instructions.
|
||||
log_in_to_delete: You must be logged in to proceed with account deletion.
|
||||
deletion_scheduled: Your account deletion is scheduled. You'll be notified when it's deleted.
|
||||
removed_identity: Your %{provider} account was successfully removed.
|
||||
updated_config: Your config has been updated. Refresh to see all changes.
|
||||
updated_profile: Your profile was successfully updated.
|
||||
token_expired: Your token has expired, please request a new one. Tokens only last for 12 hours after account deletion is initiated.
|
||||
video_states_controller:
|
||||
related_article_not_found: Related article not found
|
||||
video_state_updated: Video state updated
|
||||
121
config/locales/controllers/fr.yml
Normal file
121
config/locales/controllers/fr.yml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
---
|
||||
fr:
|
||||
api_secrets_controller:
|
||||
generated: 'Your API Key has been generated: %{secret}'
|
||||
revoked: Your API Key has been revoked.
|
||||
application_controller:
|
||||
bad_request: 'Error: Bad Request'
|
||||
not_authorized: 'Error: not authorized'
|
||||
please_sign_in: Please sign in
|
||||
articles_controller:
|
||||
deleted: Article was successfully deleted.
|
||||
comments_controller:
|
||||
create:
|
||||
success: created
|
||||
failure: comment already exists
|
||||
delete:
|
||||
error: Something went wrong; Comment NOT deleted.
|
||||
notice: Comment was successfully deleted.
|
||||
markdown: 'There was an error in your markdown: %{error}'
|
||||
markdown_html: "<p>😔 There was an error in your markdown</p><hr><p>%{error}</p>"
|
||||
moderated: Not allowed due to moderation action
|
||||
confirmations_controller:
|
||||
email_sent: Email sent! Please contact support at %{email} if you are having trouble receiving your confirmation instructions.
|
||||
credits_controller:
|
||||
done:
|
||||
one: "%{count} new credits purchased!"
|
||||
other: "%{count} new credits purchased!"
|
||||
devices_controller:
|
||||
not_found: Not Found
|
||||
discussion_locks_controller:
|
||||
locked: Discussion was successfully locked!
|
||||
unlocked: Discussion was successfully unlocked!
|
||||
email_subscriptions_controller:
|
||||
badge_notifications: badge notifications
|
||||
comment_notifications: comment notifications
|
||||
digest_emails: "%{community} digest emails"
|
||||
follower_notifications: follower notifications
|
||||
mention_notifications: mention notifications
|
||||
this_list: this list
|
||||
unread_notifications: unread notifications
|
||||
feedback_messages_controller:
|
||||
error_fill: "Make sure the forms are filled. 🤖 Other possible errors: %{errors}"
|
||||
n_a: N/A
|
||||
submitted: Your report is submitted
|
||||
follows_controller:
|
||||
already_followed: already followed
|
||||
daily_limit: Daily account follow limit reached!
|
||||
followed: followed
|
||||
unfollowed: unfollowed
|
||||
github_repos_controller:
|
||||
repo_not_found: GitHub repository not found
|
||||
github_unauthorized: 'GitHub Unauthorized: %{e_message}'
|
||||
image_uploads_controller:
|
||||
server_error: A server error has occurred!
|
||||
listings_controller:
|
||||
deleted: Listing was successfully deleted.
|
||||
no_credit: Not enough available credits
|
||||
omniauth_callbacks_controller:
|
||||
log_in_error: 'Log in error: %{e}'
|
||||
username_taken: username has already been taken
|
||||
organizations_controller:
|
||||
secret_updated: Your org secret was updated
|
||||
deletion_scheduled: 'Your organization: "%{organization_name}" deletion is scheduled. You''ll be notified when it''s deleted.'
|
||||
not_deleted: Your organization was not deleted; you must be an admin, the only member in the organization, and have no articles connected to the organization.
|
||||
created: Your organization was successfully created and you are an admin.
|
||||
updated: Your organization was successfully updated.
|
||||
podcasts_controller:
|
||||
podcast_suggested: Podcast suggested
|
||||
profiles_controller:
|
||||
updated: Your profile has been updated
|
||||
rating_votes_controller:
|
||||
not_upserted_successfully: Not Upserted Successfully
|
||||
registrations_controller:
|
||||
error:
|
||||
recaptcha: You must complete the recaptcha ✅
|
||||
domain: is not included in allowed domains.
|
||||
response_templates_controller:
|
||||
response_template_error: 'Response template error: %{errors}'
|
||||
created: Your response template "%{title}" was created.
|
||||
deleted: Your response template "%{title}" was deleted.
|
||||
updated: Your response template "%{title}" was updated.
|
||||
social_previews_controller:
|
||||
fonts: Roboto|Roboto+Condensed
|
||||
stories:
|
||||
pinned_articles_controller:
|
||||
not_found: not found
|
||||
stories_controller:
|
||||
404_bio_not_found: 404 bio not found
|
||||
searching: "...searching"
|
||||
stripe_active_cards_controller:
|
||||
cannot_remove: Can't remove card if you have an active membership. Please cancel your membership first.
|
||||
cannot_update: There was a problem updating your billing info.
|
||||
updated: Your billing information has been updated
|
||||
removed: Your card has been successfully removed.
|
||||
tag_adjustments_controller:
|
||||
failure: 'Failure: %{errors}'
|
||||
destroyed: Tag adjustment destroyed
|
||||
tags_controller:
|
||||
tag_successfully_updated: "Tag successfully updated! 👍 "
|
||||
users_controller:
|
||||
removed_admin: "%{name} is no longer an admin."
|
||||
removed_member: "%{name} is no longer part of your organization."
|
||||
added_admin: "%{name} is now an admin."
|
||||
provide_email: Please, provide an email to delete your account.
|
||||
provide_email_delete: Please, provide an email to delete your account
|
||||
send_export: " The export will be emailed to you shortly."
|
||||
invalid_secret: The given organization secret was invalid.
|
||||
username_blank: Username cannot be blank
|
||||
deletion_in_progress: You have already requested account deletion. Please, check your email for further instructions.
|
||||
joined_org: You have joined the %{organization_name} organization.
|
||||
left_org: You have left your organization.
|
||||
deletion_requested: You have requested account deletion. Please, check your email for further instructions.
|
||||
log_in_to_delete: You must be logged in to proceed with account deletion.
|
||||
deletion_scheduled: Your account deletion is scheduled. You'll be notified when it's deleted.
|
||||
removed_identity: Your %{provider} account was successfully removed.
|
||||
updated_config: Your config has been updated. Refresh to see all changes.
|
||||
updated_profile: Your profile was successfully updated.
|
||||
token_expired: Your token has expired, please request a new one. Tokens only last for 12 hours after account deletion is initiated.
|
||||
video_states_controller:
|
||||
related_article_not_found: Related article not found
|
||||
video_state_updated: Video state updated
|
||||
5
config/locales/decorators/en.yml
Normal file
5
config/locales/decorators/en.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
en:
|
||||
decorators:
|
||||
article_decorator:
|
||||
tagged_with: " Tagged with %{cached_tag_list}."
|
||||
5
config/locales/decorators/fr.yml
Normal file
5
config/locales/decorators/fr.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
fr:
|
||||
decorators:
|
||||
article_decorator:
|
||||
tagged_with: " Tagged with %{cached_tag_list}."
|
||||
|
|
@ -145,6 +145,7 @@ en:
|
|||
equal_to: must be equal to %{count}
|
||||
even: must be even
|
||||
exclusion: is reserved
|
||||
general: 'Error: %{errors}'
|
||||
greater_than: must be greater than %{count}
|
||||
greater_than_or_equal_to: must be greater than or equal to %{count}
|
||||
inclusion: is not included in the list
|
||||
|
|
@ -165,6 +166,7 @@ en:
|
|||
too_short:
|
||||
one: is too short (minimum is 1 character)
|
||||
other: is too short (minimum is %{count} characters)
|
||||
try_again_email: 'An error occurred. Please try again or send an email to: %{email}'
|
||||
wrong_length:
|
||||
one: is the wrong length (should be 1 character)
|
||||
other: is the wrong length (should be %{count} characters)
|
||||
|
|
@ -176,6 +178,7 @@ en:
|
|||
medium: "%b %-d, %Y"
|
||||
reddit: "%b %e '%y"
|
||||
short: "%b %-e"
|
||||
short_with_yy: "%b %-d '%y"
|
||||
short_with_year: "%b %-e, %Y"
|
||||
stackexchange: "%b %e '%y"
|
||||
tweet: "%H:%M %p - %d %b %Y"
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ fr:
|
|||
even: doit être pair
|
||||
exclusion: est réservé
|
||||
expired: a expiré, veuillez en demander un nouveau
|
||||
general: 'Error: %{errors}'
|
||||
greater_than: doit être supérieur à %{count}
|
||||
greater_than_or_equal_to: doit être supérieur ou égal à %{count}
|
||||
inclusion: n'est pas inclus dans la liste
|
||||
|
|
@ -188,6 +189,7 @@ fr:
|
|||
too_short:
|
||||
one: est trop court (au moins 1 caractère)
|
||||
other: est trop court (le minimum est de %{count} caractères)
|
||||
try_again_email: 'An error occurred. Please try again or send an email to: %{email}'
|
||||
wrong_length:
|
||||
one: est la mauvaise longueur (devrait être 1 caractère)
|
||||
other: est la mauvaise longueur (devrait être %{count} caractères)
|
||||
|
|
@ -199,6 +201,7 @@ fr:
|
|||
medium: "%b %-d, %Y"
|
||||
reddit: "%b %e '%y"
|
||||
short: "%-e %b"
|
||||
short_with_yy: "%-e %b '%y"
|
||||
short_with_year: "%-e %b, %Y"
|
||||
stackexchange: "%b %e '%y"
|
||||
tweet: "%H:%M %p - %d %b %Y"
|
||||
|
|
|
|||
|
|
@ -10,12 +10,6 @@ en:
|
|||
title_rel: "%{root} — %{site}"
|
||||
title_root: "[Discussion] %{title} — %{site}"
|
||||
description: "%{site} Comment"
|
||||
messages:
|
||||
create:
|
||||
success: created
|
||||
failure: comment already exists
|
||||
markdown: 'There was an error in your markdown: %{error}'
|
||||
markdown_html: "<p>😔 There was an error in your markdown</p><hr><p>%{error}</p>"
|
||||
parent:
|
||||
subtitle_html: "%{start}Discussion on: %{end}%{title}"
|
||||
metadata_html: "%{name}%{on}"
|
||||
|
|
@ -31,8 +25,6 @@ en:
|
|||
heading: Are you sure you want to delete this comment?
|
||||
desc_html: You cannot undo this action, perhaps you just want to %{action} instead?
|
||||
action: Edit
|
||||
error: Something went wrong; Comment NOT deleted.
|
||||
notice: Comment was successfully deleted.
|
||||
submit: Delete
|
||||
edit: Edit
|
||||
cancel: Dismiss
|
||||
|
|
|
|||
|
|
@ -10,12 +10,6 @@ fr:
|
|||
title_rel: "%{root} — %{site}"
|
||||
title_root: "[Discussion] %{title} — %{site}"
|
||||
description: "%{site} Comment"
|
||||
messages:
|
||||
create:
|
||||
success: created
|
||||
failure: comment already exists
|
||||
markdown: 'There was an error in your markdown: %{error}'
|
||||
markdown_html: "<p>😔 There was an error in your markdown</p><hr><p>%{error}</p>"
|
||||
parent:
|
||||
subtitle_html: "%{start}Discussion on: %{end}%{title}"
|
||||
metadata_html: "%{name}%{on}"
|
||||
|
|
@ -31,8 +25,6 @@ fr:
|
|||
heading: Are you sure you want to delete this comment?
|
||||
desc_html: You cannot undo this action, perhaps you just want to %{action} instead?
|
||||
action: Edit
|
||||
error: Something went wrong; Comment NOT deleted.
|
||||
notice: Comment was successfully deleted.
|
||||
submit: Delete
|
||||
edit: Edit
|
||||
cancel: Dismiss
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ RSpec.describe "/confirm-email", type: :system do
|
|||
click_button "Resend"
|
||||
|
||||
expect(page).to have_current_path(user_confirmation_path)
|
||||
expected_message = format(ConfirmationsController::FLASH_MESSAGE,
|
||||
email: ForemInstance.email)
|
||||
expected_message = I18n.t("confirmations_controller.email_sent", email: ForemInstance.email)
|
||||
expect(page).to have_content(expected_message)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue