]> git.openstreetmap.org Git - rails.git/commitdiff
Merge remote-tracking branch 'upstream/pull/5403'
authorTom Hughes <tom@compton.nu>
Mon, 10 Feb 2025 18:54:14 +0000 (18:54 +0000)
committerTom Hughes <tom@compton.nu>
Mon, 10 Feb 2025 18:54:14 +0000 (18:54 +0000)
1  2 
app/controllers/application_controller.rb
app/controllers/site_controller.rb
config/locales/en.yml
config/settings.yml

index 176fd8c2e060213d8264c1ccd1dd8cddca281df6,90866fe76986a9805f2ed680d429a265eb2bf86f..a7235241c14f95f46661073c7fe01e7165d6d246
@@@ -20,7 -20,7 +20,7 @@@ class ApplicationController < ActionCon
    helper_method :oauth_token
  
    def self.allow_thirdparty_images(**options)
 -    content_security_policy(options) do |policy|
 +    content_security_policy(**options) do |policy|
        policy.img_src("*", :data)
      end
    end
        # don't allow access to any auth-requiring part of the site unless
        # the new CTs have been seen (and accept/decline chosen).
        elsif !current_user.terms_seen && flash[:skip_terms].nil?
 -        flash[:notice] = t "users.terms.you need to accept or decline"
 +        flash[:notice] = t "accounts.terms.show.you need to accept or decline"
          if params[:referer]
 -          redirect_to :controller => "users", :action => "terms", :referer => params[:referer]
 +          redirect_to account_terms_path(:referer => params[:referer])
          else
 -          redirect_to :controller => "users", :action => "terms", :referer => request.fullpath
 +          redirect_to account_terms_path(:referer => request.fullpath)
          end
        end
      end
  
    def check_database_writable(need_api: false)
      if Settings.status == "database_offline" || Settings.status == "database_readonly" ||
 -       (need_api && (Settings.status == "api_offline" || Settings.status == "api_readonly"))
 +       (need_api && %w[api_offline api_readonly].include?(Settings.status))
        if request.xhr?
          report_error "Database offline for maintenance", :service_unavailable
        else
  
      request.content_security_policy = policy
  
-     case Settings.status
-     when "database_offline", "api_offline"
-       flash.now[:warning] = t("layouts.osm_offline")
-     when "database_readonly", "api_readonly"
-       flash.now[:warning] = t("layouts.osm_read_only")
-     end
+     flash.now[:warning] = { :partial => "layouts/offline_flash" } unless api_status == "online"
  
      request.xhr? ? "xhr" : "map"
    end
    end
  
    def deny_access(_exception)
 -    if doorkeeper_token
 -      set_locale
 -      report_error t("oauth.permissions.missing"), :forbidden
 -    elsif current_user
 +    if current_user
        set_locale
        respond_to do |format|
          format.html { redirect_to :controller => "/errors", :action => "forbidden" }
      begin
        referer = URI.parse(referer)
  
 -      if referer.scheme == "http" || referer.scheme == "https"
 +      if %w[http https].include?(referer.scheme)
          referer.scheme = nil
          referer.host = nil
          referer.port = nil
  
      referer&.to_s
    end
 -
 -  def scope_enabled?(scope)
 -    doorkeeper_token&.includes_scope?(scope)
 -  end
 -
 -  helper_method :scope_enabled?
  end
index 9adbaa1953fd9fe774bf9bb90eb130da53aed90e,aa107bcb6b6cebe842a0d83a2492f2f5ab514275..5110be0197ab21face71e30427ac5b29c04b7092
@@@ -24,7 -24,7 +24,7 @@@ class SiteController < ApplicationContr
    end
  
    def index
 -    session[:location] ||= OSM.ip_location(request.env["REMOTE_ADDR"]) unless Settings.status == "database_readonly" || Settings.status == "database_offline"
 +    session[:location] ||= OSM.ip_location(request.env["REMOTE_ADDR"]) unless %w[database_readonly database_offline].include?(Settings.status)
    end
  
    def permalink
      rescue ActiveRecord::RecordNotFound
        # don't try and derive a location from a missing/deleted object
      end
+     if api_status != "online"
+       flash.now[:warning] = { :partial => "layouts/offline_flash" }
+     elsif current_user && !current_user.data_public?
+       flash.now[:warning] = { :partial => "not_public_flash" }
+     else
+       @enable_editor = true
+     end
    end
  
    def copyright
    def export; end
  
    def offline
-     flash.now[:warning] = if Settings.status == "database_offline"
-                             t("layouts.osm_offline")
-                           else
-                             t("layouts.osm_read_only")
-                           end
+     flash.now[:warning] = { :partial => "layouts/offline_flash" }
      render :html => nil, :layout => true
    end
  
diff --combined config/locales/en.yml
index 7b2be6a0cb63180d6a2a1376550d2688d2d7fc40,f79bee19d6fc2ff022e946533d19078bfa71a4c9..cb7e24ee0d580b302a79be9aeeaa4271763e8f31
@@@ -20,6 -20,9 +20,6 @@@ en
          create: Add Comment
        message:
          create: Send
 -      client_application:
 -        create: Register
 -        update: Update
        oauth2_application:
          create: Register
          update: Update
@@@ -89,7 -92,7 +89,7 @@@
          support_url: Support URL
          allow_read_prefs:  read their user preferences
          allow_write_prefs: modify their user preferences
 -        allow_write_diary: create diary entries, comments and make friends
 +        allow_write_diary: create diary entries and comments
          allow_write_api:   modify the map
          allow_read_gpx:    read their private GPS traces
          allow_write_gpx:   upload GPS traces
        entry:
          comment: Comment
          full: Full note
 -  account:
 -    deletions:
 -      show:
 -        title: Delete My Account
 -        warning: Warning! The account deletion process is final, and cannot be reversed.
 -        delete_account: Delete Account
 -        delete_introduction: "You can delete your OpenStreetMap account using the button below. Please note the following details:"
 -        delete_profile: Your profile information, including your avatar, description and home location will be removed.
 -        delete_display_name: Your display name will be removed, and can be reused by other accounts.
 -        retain_caveats: "However, some information about you will be retained on OpenStreetMap, even after your account is deleted:"
 -        retain_edits: Your edits to the map database, if any, will be retained.
 -        retain_traces: Your uploaded traces, if any, will be retained.
 -        retain_diary_entries: Your diary entries and diary comments, if any, will be retained but hidden from view.
 -        retain_notes: Your map notes and note comments, if any, will be retained but hidden from view.
 -        retain_changeset_discussions: Your changeset discussions, if any, will be retained.
 -        retain_email: Your email address will be retained.
 -        recent_editing_html: "As you have edited recently your account cannot currently be deleted. Deletion will be possible in %{time}."
 -        confirm_delete: Are you sure?
 -        cancel: Cancel
    accounts:
      edit:
        title: "Edit account"
        openid:
          link: "https://wiki.openstreetmap.org/wiki/OpenID"
          link text: "what is this?"
 -      public editing:
 -        heading: "Public editing"
 -        enabled: "Enabled. Not anonymous and can edit data."
 -        enabled link: "https://wiki.openstreetmap.org/wiki/Anonymous_edits"
 -        enabled link text: "what is this?"
 -        disabled: "Disabled and cannot edit data, all previous edits are anonymous."
 -        disabled link text: "why can't I edit?"
        contributor terms:
          heading: "Contributor Terms"
          agreed: "You have agreed to the new Contributor Terms."
        success: "User information updated successfully."
      destroy:
        success: "Account Deleted."
 +    deletions:
 +      show:
 +        title: Delete My Account
 +        warning: Warning! The account deletion process is final, and cannot be reversed.
 +        delete_account: Delete Account
 +        delete_introduction: "You can delete your OpenStreetMap account using the button below. Please note the following details:"
 +        delete_profile: Your profile information, including your avatar, description and home location will be removed.
 +        delete_display_name: Your display name will be removed, and can be reused by other accounts.
 +        retain_caveats: "However, some information about you will be retained on OpenStreetMap, even after your account is deleted:"
 +        retain_edits: Your edits to the map database, if any, will be retained.
 +        retain_traces: Your uploaded traces, if any, will be retained.
 +        retain_diary_entries: Your diary entries and diary comments, if any, will be retained but hidden from view.
 +        retain_notes: Your map notes and note comments, if any, will be retained but hidden from view.
 +        retain_changeset_discussions: Your changeset discussions, if any, will be retained.
 +        retain_email: Your email address will be retained.
 +        recent_editing_html: "As you have edited recently your account cannot currently be deleted. Deletion will be possible in %{time}."
 +        confirm_delete: Are you sure?
 +        cancel: Cancel
 +    terms:
 +      show:
 +        title: "Terms"
 +        heading: "Terms"
 +        heading_ct: "Contributor terms"
 +        read and accept with tou: "Please read the contributor agreement and the terms of use, check both checkboxes when done and then press the continue button."
 +        contributor_terms_explain: "This agreement governs the terms for your existing and future contributions."
 +        read_ct: "I have read and agree to the above contributor terms"
 +        tou_explain_html: "These %{tou_link} govern the use of the website and other infrastructure provided by the OSMF. Please click on the link, read and agree to the text."
 +        read_tou: "I have read and agree to the Terms of Use"
 +        consider_pd: "In addition to the above, I consider my contributions to be in the Public Domain"
 +        consider_pd_why: "what's this?"
 +        consider_pd_why_url: https://osmfoundation.org/wiki/Licence_and_Legal_FAQ/Why_would_I_want_my_contributions_to_be_public_domain
 +        guidance_info_html: "Information to help understand these terms: a %{readable_summary_link} and some %{informal_translations_link}"
 +        readable_summary: human readable summary
 +        informal_translations: informal translations
 +        continue: "Continue"
 +        cancel: "Cancel"
 +        you need to accept or decline: "Please read and then either accept or decline the new Contributor Terms to continue."
 +        legale_select: "Country of residence:"
 +        legale_names:
 +          france: "France"
 +          italy: "Italy"
 +          rest_of_world: "Rest of the world"
 +      update:
 +        terms accepted: "Thanks for accepting the new contributor terms!"
 +      terms_declined_flash:
 +        terms_declined_html: We are sorry that you have decided to not accept the new Contributor Terms. For more information, please see %{terms_declined_link}.
 +        terms_declined_link: this wiki page
 +        terms_declined_url: https://wiki.openstreetmap.org/wiki/Contributor_Terms_Declined
    browse:
      deleted_ago_by_html: "Deleted %{time_ago} by %{user}"
      edited_ago_by_html: "Edited %{time_ago} by %{user}"
      view_history: "View History"
      view_unredacted_history: "View Unredacted History"
      view_details: "View Details"
 -    view_redacted_data: "View Redacted Data"
 -    view_redaction_message: "View Redaction Message"
      location: "Location:"
      common_details:
        coordinates_html: "%{latitude}, %{longitude}"
      node:
        title_html: "Node: %{name}"
 -      history_title_html: "Node History: %{name}"
      way:
        title_html: "Way: %{name}"
 -      history_title_html: "Way History: %{name}"
        nodes: "Nodes"
        nodes_count:
          one: "%{count} node"
          other: "part of ways %{related_ways}"
      relation:
        title_html: "Relation: %{name}"
 -      history_title_html: "Relation History: %{name}"
        members: "Members"
        members_count:
          one: "%{count} member"
        entry_role_html: "%{relation_name} (as %{relation_role})"
      not_found:
        title: Not Found
 -      sorry: "Sorry, %{type} #%{id} could not be found."
 -      type:
 -        node: node
 -        way: way
 -        relation: relation
 -        changeset: changeset
 -        note: note
      timeout:
        title: Timeout Error
        sorry: "Sorry, the data for the %{type} with the id %{id} took too long to retrieve."
          relation: "relation"
      start_rjs:
        feature_warning: "Loading %{num_features} features, which may make your browser slow or unresponsive. Are you sure you want to display this data?"
 +      feature_error: "Features could not be loaded: %{message}"
        load_data: "Load Data"
        loading: "Loading..."
      tag_details:
        introduction: "Click on the map to find nearby features."
        nearby: "Nearby features"
        enclosing: "Enclosing features"
 +  old_elements:
 +    index:
 +      node:
 +        title_html: "Node History: %{name}"
 +      way:
 +        title_html: "Way History: %{name}"
 +      relation:
 +        title_html: "Relation History: %{name}"
 +    actions:
 +      view_redacted_data: "View Redacted Data"
 +      view_redaction_message: "View Redaction Message"
    nodes:
 +    not_found_message:
 +      sorry: "Sorry, node #%{id} could not be found."
      timeout:
        sorry: "Sorry, the data for the node with the id %{id} took too long to retrieve."
    old_nodes:
 -    not_found:
 +    not_found_message:
        sorry: "Sorry, node #%{id} version %{version} could not be found."
      timeout:
        sorry: "Sorry, the history of the node with the id %{id} took too long to retrieve."
    ways:
 +    not_found_message:
 +      sorry: "Sorry, way #%{id} could not be found."
      timeout:
        sorry: "Sorry, the data for the way with the id %{id} took too long to retrieve."
    old_ways:
 -    not_found:
 +    not_found_message:
        sorry: "Sorry, way #%{id} version %{version} could not be found."
      timeout:
        sorry: "Sorry, the history of the way with the id %{id} took too long to retrieve."
    relations:
 +    not_found_message:
 +      sorry: "Sorry, relation #%{id} could not be found."
      timeout:
        sorry: "Sorry, the data for the relation with the id %{id} took too long to retrieve."
    old_relations:
 -    not_found:
 +    not_found_message:
        sorry: "Sorry, relation #%{id} version %{version} could not be found."
      timeout:
        sorry: "Sorry, the history of the relation with the id %{id} took too long to retrieve."
        title: "Changesets"
        title_user: "Changesets by %{user}"
        title_user_link_html: "Changesets by %{user_link}"
 -      title_friend: "Changesets by my friends"
 +      title_followed: "Changesets by followings"
        title_nearby: "Changesets by nearby users"
        empty: "No changesets found."
        empty_area: "No changesets in this area."
          created: "Created"
          closed: "Closed"
          belongs_to: "Author"
 -    subscribe:
 -      heading: Subscribe to the following changeset discussion?
 -      button: Subscribe to discussion
 -    unsubscribe:
 -      heading: Unsubscribe from the following changeset discussion?
 -      button: Unsubscribe from discussion
 -    heading:
 -      title: "Changeset %{id}"
 -      created_by_html: "Created by %{link_user} on %{created}."
 -    no_such_entry:
 -      heading: "No entry with the id: %{id}"
 -      body: "Sorry, there is no changeset with the id %{id}. Please check your spelling, or maybe the link you clicked is wrong."
      show:
        title: "Changeset: %{id}"
        created: "Created: %{when}"
        ways_paginated: "Ways (%{x}-%{y} of %{count})"
        relations: "Relations (%{count})"
        relations_paginated: "Relations (%{x}-%{y} of %{count})"
 +    not_found_message:
 +      sorry: "Sorry, changeset #%{id} could not be found."
      timeout:
        sorry: "Sorry, the list of changesets you requested took too long to retrieve."
 +  changeset_subscriptions:
 +    show:
 +      subscribe:
 +        heading: Subscribe to the following changeset discussion?
 +        button: Subscribe to discussion
 +      unsubscribe:
 +        heading: Unsubscribe from the following changeset discussion?
 +        button: Unsubscribe from discussion
 +    heading:
 +      title: "Changeset %{id}"
 +      created_by_html: "Created by %{link_user} on %{created}."
 +    no_such_entry:
 +      heading: "No entry with the id: %{id}"
 +      body: "Sorry, there is no changeset with the id %{id}. Please check your spelling, or maybe the link you clicked is wrong."
    dashboards:
      contact:
        km away: "%{count}km away"
      popup:
        your location: "Your location"
        nearby mapper: "Nearby mapper"
 -      friend: "Friend"
 +      following: "Following"
      show:
        title: My Dashboard
        no_home_location_html: "%{edit_profile_link} and set your home location to see nearby users."
        edit_your_profile: Edit your profile
 -      my friends: My friends
 -      no friends: You have not added any friends yet.
 +      followings: Followings
 +      no followings: You have not followed any user yet.
        nearby users: "Other nearby users"
        no nearby users: "There are no other users who admit to mapping nearby yet."
 -      friends_changesets: "friends' changesets"
 -      friends_diaries: "friends' diary entries"
 +      followed_changesets: "changesets"
 +      followed_diaries: "diary entries"
        nearby_changesets: "nearby user changesets"
        nearby_diaries: "nearby user diary entries"
    diary_entries:
        use_map_link: Use Map
      index:
        title: "Users' Diaries"
 -      title_friends: "Friends' Diaries"
 +      title_followed: "Followings' Diaries"
        title_nearby: "Nearby Users' Diaries"
        user_title: "%{user}'s Diary"
        in_language_title: "Diary Entries in %{language}"
        heading: Unsubscribe from the following diary entry discussion?
        button: Unsubscribe from discussion
    diary_comments:
 -    index:
 -      title: "Diary Comments added by %{user}"
 -      heading: "%{user}'s Diary Comments"
 -      subheading_html: "Diary Comments added by %{user}"
 -      no_comments: "No diary comments"
 -    page:
 -      post: Post
 -      when: When
 -      comment: Comment
      new:
        heading: Add a comment to the following diary entry discussion?
    doorkeeper:
      not_found:
        title: File not found
        description: Couldn't find a file/directory/API operation by that name on the OpenStreetMap server (HTTP 404)
 -  friendships:
 -    make_friend:
 -      heading: "Add %{user} as a friend?"
 -      button: "Add as friend"
 -      success: "%{name} is now your friend!"
 -      failed: "Sorry, failed to add %{name} as a friend."
 -      already_a_friend: "You are already friends with %{name}."
 -      limit_exceeded: "You have friended a lot of users recently. Please wait a while before trying to friend any more."
 -    remove_friend:
 -      heading: "Unfriend %{user}?"
 -      button: "Unfriend"
 -      success: "%{name} was removed from your friends."
 -      not_a_friend: "%{name} is not one of your friends."
 +  follows:
 +    show:
 +      follow:
 +        heading: "Do you want to follow %{user}?"
 +        button: "Follow User"
 +      unfollow:
 +        heading: "Do you want to unfollow %{user}?"
 +        button: "Unfollow User"
 +    create:
 +      success: "You are now following %{name}!"
 +      failed: "Sorry, your request to follow %{name} has failed."
 +      already_followed: "You already follow %{name}."
 +      limit_exceeded: "You have followed a lot of users recently. Please wait a while before trying to follow any more."
 +    destroy:
 +      success: "You successfully unfollowed %{name}."
 +      not_followed: "You are not following %{name}."
    geocoder:
      search:
        title:
            census: "Census Boundary"
            national_park: "National Park"
            political: "Electoral Boundary"
 -          protected_area : "Protected Area"
 +          protected_area: "Protected Area"
            "yes": "Boundary"
          bridge:
            aqueduct: "Aqueduct"
            turning_circle: "Turning Circle"
            turning_loop: "Turning Loop"
            unclassified: "Unclassified Road"
 -          "yes" : "Road"
 +          "yes": "Road"
          historic:
            aircraft: "Historic Aircraft"
            archaeological_site: "Archaeological Site"
            trench: "Trench"
            "yes": "Military"
          mountain_pass:
 -          "yes" : "Mountain Pass"
 +          "yes": "Mountain Pass"
          natural:
            atoll: "Atoll"
            bare_rock: "Bare Rock"
        reports: Reports
        last_updated: Last Updated
        last_updated_time_ago_user_html: "%{time_ago} by %{user}"
 +      reporting_users: Reporting Users
        reports_count:
          one: "%{count} Report"
          other: "%{count} Reports"
 +      more_reporters: "and %{count} more"
        reported_item: Reported Item
        states:
          ignored: Ignored
        reopened: Issue status has been set to 'Open'
      comments:
        comment_from_html: "Comment from %{user_link} on %{comment_created_at}"
 -      reassign_param: Reassign Issue?
 +      reassign_to_moderators: Reassign Issue to Moderators
 +      reassign_to_administrators: Reassign Issue to Administrators
      reports:
        reported_by_html: "Reported as %{category} by %{user} on %{updated_at}"
      helper:
      partners_corpmembers: "OSMF corporate members"
      partners_partners: "partners"
      tou: "Terms of Use"
-     osm_offline: "The OpenStreetMap database is currently offline while essential database maintenance work is carried out."
-     osm_read_only: "The OpenStreetMap database is currently in read-only mode while essential database maintenance work is carried out."
      nothing_to_preview: "Nothing to preview."
      help: Help
      about: About
      communities: Communities
      learn_more: "Learn More"
      more: More
+     offline_flash:
+       osm_offline: "The OpenStreetMap database is currently offline while essential maintenance work is carried out."
+       osm_read_only: "The OpenStreetMap database is currently in read-only mode while essential maintenance work is carried out."
+       expected_restore_html: "Services are expected to be restored in %{time}."
+       announcement: "You can read the announcement here."
    user_mailer:
      diary_comment_notification:
        description: "OpenStreetMap Diary Entry #%{id}"
        header_html: "%{from_user} has sent you a message through OpenStreetMap with the subject %{subject}:"
        footer: "You can also read the message at %{readurl} and you can send a message to the author at %{replyurl}"
        footer_html: "You can also read the message at %{readurl} and you can send a message to the author at %{replyurl}"
 -    friendship_notification:
 +    follow_notification:
        hi: "Hi %{to_user},"
 -      subject: "[OpenStreetMap] %{user} added you as a friend"
 -      had_added_you: "%{user} has added you as a friend on OpenStreetMap."
 +      subject: "[OpenStreetMap] %{user} followed you"
 +      followed_you: "%{user} is now following you on OpenStreetMap."
        see_their_profile: "You can see their profile at %{userurl}."
        see_their_profile_html: "You can see their profile at %{userurl}."
 -      befriend_them: "You can also add them as a friend at %{befriendurl}."
 -      befriend_them_html: "You can also add them as a friend at %{befriendurl}."
 -    gpx_description:
 -      description_with_tags: "It looks like your file %{trace_name} with the description %{trace_description} and the following tags: %{tags}"
 -      description_with_tags_html: "It looks like your file %{trace_name} with the description %{trace_description} and the following tags: %{tags}"
 -      description_with_no_tags: "It looks like your file %{trace_name} with the description %{trace_description} and no tags"
 -      description_with_no_tags_html: "It looks like your file %{trace_name} with the description %{trace_description} and no tags"
 +      follow_them: "You can also follow them at %{followurl}."
 +      follow_them_html: "You can also follow them at %{followurl}."
 +    gpx_details:
 +      details: "Your file details:"
 +      filename: Filename
 +      url: URL
 +      description: Description
 +      tags: Tags
 +      total_points: Total number of points
 +      imported_points: Number of imported points
      gpx_failure:
        hi: "Hi %{to_user},"
 -      failed_to_import: "failed to be imported as a GPS trace file. Please verify that your file is a valid GPX file or an archive containing GPX file(s) in the supported format (.tar.gz, .tar.bz2, .tar, .zip, .gpx.gz, .gpx.bz2). Could there be a format or syntax issue with your file? Here is the importing error:"
 -      more_info: "More information about GPX import failures and how to avoid them can be found at %{url}."
 +      failed_to_import: "It looks like your file failed to be imported as a GPS trace."
 +      verify: "Please verify that your file is a valid GPX file or an archive containing GPX file(s) in the supported format (.tar.gz, .tar.bz2, .tar, .zip, .gpx.gz, .gpx.bz2). Could there be a format or syntax issue with your file? Here is the importing error:"
 +      more_info: "More information about GPX import failures and how to avoid them can be found at %{url}"
        more_info_html: "More information about GPX import failures and how to avoid them can be found at %{url}."
        import_failures_url: "https://wiki.openstreetmap.org/wiki/GPX_Import_Failures"
        subject: "[OpenStreetMap] GPX Import failure"
      gpx_success:
        hi: "Hi %{to_user},"
 -      loaded:
 -        one: "loaded successfully with %{trace_points} out of a possible %{count} point."
 -        other: "loaded successfully with %{trace_points} out of a possible %{count} points."
 -      trace_location: "Your trace is available at %{trace_url}"
 +      imported_successfully: "It looks like your file was imported successfully as a GPS trace."
        all_your_traces: "All your successfully uploaded GPX traces can be found at %{url}"
        all_your_traces_html: "All your successfully uploaded GPX traces can be found at %{url}."
        subject: "[OpenStreetMap] GPX Import success"
        success: "Confirmed your account, thanks for signing up!"
        already active: "This account has already been confirmed."
        unknown token: "That confirmation code has expired or does not exist."
 -      resend_html: "If you need us to resend the confirmation email, %{reconfirm_link}."
 -      click_here: click here
 +      if_need_resend: "If you need us to resend the confirmation email, click the button below."
 +      resend_button: Resend the confirmation email
      confirm_resend:
        failure: "User %{name} not found."
      confirm_email:
        confirmation_sent: We've sent a new confirmation note to %{email} and as soon as you confirm your account you'll be able to get mapping.
        whitelist: If you use an antispam system which sends confirmation requests then please make sure you whitelist %{sender} as we are unable to reply to any confirmation requests.
    messages:
 -    inbox:
 -      title: "Inbox"
 -      messages: "You have %{new_messages} and %{old_messages}"
 -      new_messages:
 -        one: "%{count} new message"
 -        other: "%{count} new messages"
 -      old_messages:
 -        one: "%{count} old message"
 -        other: "%{count} old messages"
 -      no_messages_yet_html: "You have no messages yet. Why not get in touch with some of the %{people_mapping_nearby_link}?"
 -      people_mapping_nearby: "people mapping nearby"
 -    messages_table:
 -      from: "From"
 -      to: "To"
 -      subject: "Subject"
 -      date: "Date"
 -      actions: "Actions"
 -    message_summary:
 -      unread_button: "Mark as unread"
 -      read_button: "Mark as read"
 -      destroy_button: "Delete"
 -      unmute_button: "Move to Inbox"
      new:
        title: "Send message"
        send_message_to_html: "Send a new message to %{name}"
        title: "No such message"
        heading: "No such message"
        body: "Sorry there is no message with that id."
 -    outbox:
 -      title: "Outbox"
 -      messages:
 -        one: "You have %{count} sent message"
 -        other: "You have %{count} sent messages"
 -      no_sent_messages_html: "You have no sent messages yet. Why not get in touch with some of the %{people_mapping_nearby_link}?"
 -      people_mapping_nearby: "people mapping nearby"
 -    muted:
 -      title: "Muted Messages"
 -      messages:
 -        one: "%{count} muted message"
 -        other: "You have %{count} muted messages"
 -    reply:
 -      wrong_user: "You are logged in as '%{user}' but the message you have asked to reply to was not sent to that user. Please log in as the correct user in order to reply."
      show:
        title: "Read message"
        reply_button: "Reply"
        destroy_button: "Delete"
        back: "Back"
        wrong_user: "You are logged in as '%{user}' but the message you have asked to read was not sent by or to that user. Please log in as the correct user in order to read it."
 -    sent_message_summary:
 -      destroy_button: "Delete"
 -    heading:
 -      my_inbox: "My Inbox"
 -      my_outbox: "My Outbox"
 -      muted_messages: "Muted messages"
 -    mark:
 -      as_read: "Message marked as read"
 -      as_unread: "Message marked as unread"
 -    unmute:
 -      notice: "Message has been moved to Inbox"
 -      error: "The message could not be moved to the Inbox."
      destroy:
        destroyed: "Message deleted"
 +    read_marks:
 +      create:
 +        notice: "Message marked as read"
 +      destroy:
 +        notice: "Message marked as unread"
 +    mutes:
 +      destroy:
 +        notice: "Message has been moved to Inbox"
 +        error: "The message could not be moved to the Inbox."
 +    mailboxes:
 +      heading:
 +        my_inbox: "My Inbox"
 +        my_outbox: "My Outbox"
 +        muted_messages: "Muted messages"
 +      messages_table:
 +        from: "From"
 +        to: "To"
 +        subject: "Subject"
 +        date: "Date"
 +        actions: "Actions"
 +      message:
 +        unread_button: "Mark as unread"
 +        read_button: "Mark as read"
 +        destroy_button: "Delete"
 +        unmute_button: "Move to Inbox"
 +    inboxes:
 +      show:
 +        title: "Inbox"
 +        messages: "You have %{new_messages} and %{old_messages}"
 +        new_messages:
 +          one: "%{count} new message"
 +          other: "%{count} new messages"
 +        old_messages:
 +          one: "%{count} old message"
 +          other: "%{count} old messages"
 +        no_messages_yet_html: "You have no messages yet. Why not get in touch with some of the %{people_mapping_nearby_link}?"
 +        people_mapping_nearby: "people mapping nearby"
 +    muted_inboxes:
 +      show:
 +        title: "Muted Messages"
 +        messages:
 +          one: "%{count} muted message"
 +          other: "You have %{count} muted messages"
 +    outboxes:
 +      show:
 +        title: "Outbox"
 +        messages:
 +          one: "You have %{count} sent message"
 +          other: "You have %{count} sent messages"
 +        no_sent_messages_html: "You have no sent messages yet. Why not get in touch with some of the %{people_mapping_nearby_link}?"
 +        people_mapping_nearby: "people mapping nearby"
 +      message:
 +        destroy_button: "Delete"
 +    replies:
 +      new:
 +        wrong_user: "You are logged in as '%{user}' but the message you have asked to reply to was not sent to that user. Please log in as the correct user in order to reply."
    passwords:
      new:
        title: "Lost password"
    preferences:
      show:
        title: My Preferences
 -      preferred_editor: Preferred Editor
 -      preferred_languages: Preferred Languages
        preferred_site_color_scheme: Preferred Website Color Scheme
        site_color_schemes:
          auto: Auto
          auto: Auto
          light: Light
          dark: Dark
 -      edit_preferences: Edit Preferences
 -    edit:
 -      title: Edit Preferences
        save: Update Preferences
 -      cancel: Cancel
      update:
        failure: Couldn't update preferences.
      update_success_flash:
        preview: Preview
        help: Help
      pagination:
 +      changeset_comments:
 +        older: Older Comments
 +        newer: Newer Comments
        diary_comments:
          older: Older Comments
          newer: Newer Comments
          license_url: "https://openstreetmap.org/copyright"
          project_url: "https://openstreetmap.org"
        remote_failed: "Editing failed - make sure JOSM or Merkaartor is loaded and the remote control option is enabled"
-     edit:
+     not_public_flash:
        not_public: "You have not set your edits to be public."
        not_public_description_html: "You can no longer edit the map unless you do so. You can set your edits as public from your %{user_page}."
        user_page_link: user page
        anon_edits_html: "(%{link})"
        anon_edits_link: "https://wiki.openstreetmap.org/wiki/Disabling_anonymous_edits"
        anon_edits_link_text: "Find out why this is the case."
+     edit:
        id_not_configured: "iD has not been configured"
      export:
        title: "Export"
      offline:
        heading: "GPX Storage Offline"
        message: "The GPX file storage and upload system is currently unavailable."
 -    georss:
 -      title: "OpenStreetMap GPS Traces"
 -    description:
 -      description_with_count:
 -        one: "GPX file with %{count} point from %{user}"
 -        other: "GPX file with %{count} points from %{user}"
 -      description_without_count: "GPX file from %{user}"
 +    feeds:
 +      show:
 +        title: "OpenStreetMap GPS Traces"
 +      description:
 +        description_with_count:
 +          one: "GPX file with %{count} point from %{user}"
 +          other: "GPX file with %{count} points from %{user}"
 +        description_without_count: "GPX file from %{user}"
    application:
      permission_denied: You do not have permission to access that action
      require_cookies:
        openid: Sign-in using OpenStreetMap
        read_prefs: Read user preferences
        write_prefs: Modify user preferences
 -      write_diary: Create diary entries, comments and make friends
 +      write_diary: Create diary entries and comments
        write_api: Modify the map
        read_gpx: Read private GPS traces
        write_gpx: Upload GPS traces
          contributor_terms_url: "https://osmfoundation.org/wiki/Licence/Contributor_Terms"
          contributor_terms: "contributor terms"
        continue: Sign Up
 -      terms accepted: "Thanks for accepting the new contributor terms!"
        email_help:
          privacy_policy: privacy policy
          privacy_policy_url: https://osmfoundation.org/wiki/Privacy_Policy
        consider_pd_url: https://osmfoundation.org/wiki/Licence_and_Legal_FAQ/Why_would_I_want_my_contributions_to_be_public_domain
        or: "or"
        use external auth: "or sign up with a third party"
 -    terms:
 -      title: "Terms"
 -      heading: "Terms"
 -      heading_ct: "Contributor terms"
 -      read and accept with tou: "Please read the contributor agreement and the terms of use, check both checkboxes when done and then press the continue button."
 -      contributor_terms_explain: "This agreement governs the terms for your existing and future contributions."
 -      read_ct: "I have read and agree to the above contributor terms"
 -      tou_explain_html: "These %{tou_link} govern the use of the website and other infrastructure provided by the OSMF. Please click on the link, read and agree to the text."
 -      read_tou: "I have read and agree to the Terms of Use"
 -      consider_pd: "In addition to the above, I consider my contributions to be in the Public Domain"
 -      consider_pd_why: "what's this?"
 -      consider_pd_why_url: https://osmfoundation.org/wiki/Licence_and_Legal_FAQ/Why_would_I_want_my_contributions_to_be_public_domain
 -      guidance_info_html: "Information to help understand these terms: a %{readable_summary_link} and some %{informal_translations_link}"
 -      readable_summary: human readable summary
 -      informal_translations: informal translations
 -      continue: "Continue"
 -      declined: "https://wiki.openstreetmap.org/wiki/Contributor_Terms_Declined"
 -      cancel: "Cancel"
 -      you need to accept or decline: "Please read and then either accept or decline the new Contributor Terms to continue."
 -      legale_select: "Country of residence:"
 -      legale_names:
 -        france: "France"
 -        italy: "Italy"
 -        rest_of_world: "Rest of the world"
 -    terms_declined_flash:
 -      terms_declined_html: We are sorry that you have decided to not accept the new Contributor Terms. For more information, please see %{terms_declined_link}.
 -      terms_declined_link: this wiki page
 -      terms_declined_url: https://wiki.openstreetmap.org/wiki/Contributor_Terms_Declined
      no_such_user:
        title: "No such user"
        heading: "The user %{user} does not exist"
        edits: Edits
        traces: Traces
        notes: Map Notes
 -      remove as friend: Unfriend
 -      add as friend: Add Friend
 +      unfollow: Unfollow
 +      follow: Follow
        mapper since: "Mapper since:"
        last map edit: "Last map edit:"
        no activity yet: "No activity yet"
        report: Report this User
      go_public:
        flash success: "All your edits are now public, and you are now allowed to edit."
 +    issued_blocks:
 +      show:
 +        title: "Blocks by %{name}"
 +        heading_html: "List of Blocks by %{name}"
 +        empty: "%{name} has not made any blocks yet."
 +    received_blocks:
 +      show:
 +        title: "Blocks on %{name}"
 +        heading_html: "List of Blocks on %{name}"
 +        empty: "%{name} has not been blocked yet."
 +      edit:
 +        title: "Revoking all blocks on %{block_on}"
 +        heading_html: "Revoking all blocks on %{block_on}"
 +        empty: "%{name} has no active blocks."
 +        confirm: "Are you sure you wish to revoke %{active_blocks}?"
 +        active_blocks:
 +          one: "%{count} active block"
 +          other: "%{count} active blocks"
 +        revoke: "Revoke!"
 +      destroy:
 +        flash: "All active blocks have been revoked."
      lists:
        show:
          title: Users
        user:
          summary_html: "%{name} created from %{ip_address} on %{date}"
          summary_no_ip_html: "%{name} created on %{date}"
 +    comments:
 +      index:
 +        heading_html: "%{user}'s Comments"
 +        changesets: "Changesets"
 +        diary_entries: "Diary entries"
 +        no_comments: "No comments"
 +    changeset_comments:
 +      index:
 +        title: "Changeset Comments added by %{user}"
 +      page:
 +        changeset: Changeset
 +        when: When
 +        comment: Comment
 +    diary_comments:
 +      index:
 +        title: "Diary Comments added by %{user}"
 +      page:
 +        post: Post
 +        when: When
 +        comment: Comment
      suspended:
        title: Account Suspended
        heading: Account Suspended
        title: "User blocks"
        heading: "List of user blocks"
        empty: "No blocks have been made yet."
 -    revoke_all:
 -      title: "Revoking all blocks on %{block_on}"
 -      heading_html: "Revoking all blocks on %{block_on}"
 -      empty: "%{name} has no active blocks."
 -      confirm: "Are you sure you wish to revoke %{active_blocks}?"
 -      active_blocks:
 -        one: "%{count} active block"
 -        other: "%{count} active blocks"
 -      revoke: "Revoke!"
 -      flash: "All active blocks have been revoked."
      helper:
        time_future_html: "Ends in %{time}."
        until_login: "Active until the user logs in."
          ended: "ended"
          revoked_html: "revoked by %{name}"
          active: "active"
 -        active_unread: "active unread"
 -        expired_unread: "expired unread"
 +        active_until_read: "active until read"
          read_html: "read at %{time}"
          time_in_future_title: "%{time_absolute}; in %{time_relative}"
          time_in_past_title: "%{time_absolute}; %{time_relative}"
 -    blocks_on:
 -      title: "Blocks on %{name}"
 -      heading_html: "List of Blocks on %{name}"
 -      empty: "%{name} has not been blocked yet."
 -    blocks_by:
 -      title: "Blocks by %{name}"
 -      heading_html: "List of Blocks by %{name}"
 -      empty: "%{name} has not made any blocks yet."
      show:
        title: "%{block_on} blocked by %{block_by}"
        heading_html: "%{block_on} blocked by %{block_by}"
        open_title: "Unresolved note #%{note_name}"
        closed_title: "Resolved note #%{note_name}"
        hidden_title: "Hidden note #%{note_name}"
 +      description_when_author_is_deleted: "deleted"
        event_opened_by_html: "Created by %{user} %{time_ago}"
        event_opened_by_anonymous_html: "Created by anonymous %{time_ago}"
        event_commented_by_html: "Comment from %{user} %{time_ago}"
      new:
        title: "New Note"
        intro: "Spotted a mistake or something missing? Let other mappers know so we can fix it. Move the marker to the correct position and type a note to explain the problem."
 -      anonymous_warning_html: "You are not logged in. Please %{log_in} or %{sign_up} if you want to receive updates for your note."
 +      anonymous_warning_html: "You are not logged in. Please %{log_in} or %{sign_up} to receive updates for your note and help mappers resolve it."
        anonymous_warning_log_in: "log in"
        anonymous_warning_sign_up: "sign up"
 +      counter_warning_html: "You have already posted at least %{x_anonymous_notes}, that's great for the community, thank you! Now we encourage you to %{contribute_by_yourself}, it is not that complicated, and %{community_can_help}."
 +      x_anonymous_notes:
 +        one: "%{count} anonymous note"
 +        other: "%{count} anonymous notes"
 +      counter_warning_guide_link:
 +        text: "contribute by yourself"
 +        url: https://wiki.openstreetmap.org/wiki/Beginners%27_guide
 +      counter_warning_forum_link:
 +        text: "the community can help you"
 +        url: https://community.openstreetmap.org/
        advice: "Your note is public and may be used to update the map, so don't enter personal information, or information from copyrighted maps or directory listings."
        add: Add Note
      new_readonly:
        showing_page: "Page %{page}"
        next: "Next"
        previous: "Previous"
 +    not_found_message:
 +      sorry: "Sorry, note #%{id} could not be found."
    javascripts:
      close: Close
      share:
        center_marker: "Center map on marker"
        paste_html: "Paste HTML to embed in website"
        view_larger_map: "View Larger Map"
 -      only_standard_layer: "Only the Standard, Cycle Map and Transport layers can be exported as an image"
 +      only_layers_exported_as_image: "Only the following layers can be exported as an image:"
      embed:
        report_problem: "Report a problem"
      key:
diff --combined config/settings.yml
index c79199145163359dd3a7efbc6dcb6e539c4037e1,71819c4020ae9f7c922985101c024294a34d8e5f..2e0346f0031c891d226deeddaa284adb2801cc31
@@@ -23,6 -23,10 +23,10 @@@ api_version: "0.6
  #   database_offline - database offline with site in emergency mode
  #   gpx_offline - gpx storage offline
  status: "online"
+ # Expected services restoration date added to offline flash messages
+ #status_expected_restore_date: "2024-12-18 12:00:00Z"
+ # Application status announcement url added to offline flash messages
+ #status_announcement_url: "https://en.osm.town/@osm_tech"
  # The maximum area you're allowed to request, in square degrees
  max_request_area: 0.25
  # Number of GPS trace/trackpoints returned per-page
@@@ -63,8 -67,8 +67,8 @@@ max_messages_per_hour: 6
  default_message_query_limit: 100
  # Maximum number of messages returned by inbox and outbox message api
  max_message_query_limit: 100
 -# Rate limit for friending
 -max_friends_per_hour: 60
 +# Rate limit for following
 +max_follows_per_hour: 60
  # Rate limit for changeset comments
  min_changeset_comments_per_hour: 1
  initial_changeset_comments_per_hour: 6