diff --git a/app/assets/javascripts/admin/models/version_check.js b/app/assets/javascripts/admin/models/version_check.js index 2b05fb87b..2add3b7b2 100644 --- a/app/assets/javascripts/admin/models/version_check.js +++ b/app/assets/javascripts/admin/models/version_check.js @@ -13,7 +13,7 @@ Discourse.VersionCheck = Discourse.Model.extend({ }.property('updated_at'), dataIsOld: function() { - return moment().diff(moment(this.get('updated_at')), 'hours') >= 48; + return this.get('version_check_pending') || moment().diff(moment(this.get('updated_at')), 'hours') >= 48; }.property('updated_at'), staleData: function() { diff --git a/app/assets/javascripts/admin/templates/dashboard.js.handlebars b/app/assets/javascripts/admin/templates/dashboard.js.handlebars index 621d355ee..fdc9fdd5f 100644 --- a/app/assets/javascripts/admin/templates/dashboard.js.handlebars +++ b/app/assets/javascripts/admin/templates/dashboard.js.handlebars @@ -62,16 +62,26 @@ {{#if versionCheck.staleData}}   - + {{#if versionCheck.version_check_pending}} + + {{else}} + + {{/if}} - {{i18n admin.dashboard.stale_data}} + + {{#if versionCheck.version_check_pending}} + {{i18n admin.dashboard.version_check_pending}} + {{else}} + {{i18n admin.dashboard.stale_data}} + {{/if}} + {{else}} {{ versionCheck.latest_version }} {{#if versionCheck.upToDate }} - + {{else}} {{#if versionCheck.behindByOneVersion}} diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss index 22696753c..12fed2b02 100644 --- a/app/assets/stylesheets/common/admin/admin_base.scss +++ b/app/assets/stylesheets/common/admin/admin_base.scss @@ -382,7 +382,7 @@ table { font-size: 26px; } - .update-to-date { + .up-to-date { color: green; } .updates-available { diff --git a/app/assets/stylesheets/common/components/navs.css.scss b/app/assets/stylesheets/common/components/navs.css.scss index 9206fece1..8399c97e7 100644 --- a/app/assets/stylesheets/common/components/navs.css.scss +++ b/app/assets/stylesheets/common/components/navs.css.scss @@ -56,7 +56,6 @@ padding: 0; overflow: hidden; background-color: $nav-stacked-background-color; - @include border-radius-all(4px); @include box-shadow(0 1px 0 $white); > li { border-bottom: 1px solid $nav-stacked-divider-color; @@ -66,16 +65,15 @@ > a { margin: 0; padding: 13px 13px 13px 30px; - font-weight: bold; font-size: 16px; line-height: 20px; cursor: pointer; + color: $nav-stacked-color; } } .active > a, .active .icon-chevron-right { - color: $nav-stacked-border-color-active; - text-shadow: 0 1px 0 rgba($white, 0.5); + color: $white; background-color: $nav-stacked-background-color-active; } .count { diff --git a/app/assets/stylesheets/common/foundation/variables.scss b/app/assets/stylesheets/common/foundation/variables.scss index bdb3972c4..045588dc4 100644 --- a/app/assets/stylesheets/common/foundation/variables.scss +++ b/app/assets/stylesheets/common/foundation/variables.scss @@ -71,12 +71,13 @@ $nav-pills-background-color-active: #e45735 !default; // Stacked nav +$nav-stacked-color: #534d4b !default; $nav-stacked-border-color: #ccc !default; $nav-stacked-background-color: #fafafa !default; $nav-stacked-divider-color: #e6e6e6 !default; $nav-stacked-chevron-color: #ccc !default; $nav-stacked-border-color-active: #f15b22 !default; -$nav-stacked-background-color-active: #f9e7e0 !default; +$nav-stacked-background-color-active: #e45735 !default; // Button nav diff --git a/app/assets/stylesheets/desktop/user.scss b/app/assets/stylesheets/desktop/user.scss index fef462b89..6fb35437f 100644 --- a/app/assets/stylesheets/desktop/user.scss +++ b/app/assets/stylesheets/desktop/user.scss @@ -40,7 +40,6 @@ color: $darkish_gray; } .warning { - @include border-radius-all(6px); background-color: lighten($red, 10%); padding: 5px 8px; color: $white; @@ -108,16 +107,16 @@ } .user-main { - width: 840px; + width: 850px; float: left; margin-bottom: 50px; @include medium-width { - width: 730px; + width: 735px; } @include small-width { - width: 650px; + width: 680px; } .user-content { @@ -125,21 +124,18 @@ background-color: white; border: 1px solid #ddd; margin-bottom: 10px; - @include border-radius-all(4px); } .about { background-color: #444; margin-bottom: 10px; overflow: hidden; - border: 1px solid #bbb; color: #fff; - @include border-radius-all(4px); .details { text-align: center; - padding: 10px; + padding: 12px; h1 { @@ -186,11 +182,12 @@ text-align: right; padding: 0 10px; width: 20%; - @include border-radius-all(4px); dd { color: white; margin: 0 0 7px 0; + overflow: hidden; + text-overflow: ellipsis; } dt { color: #aaa; @@ -201,9 +198,8 @@ .controls { background-color: #ddd; - margin-top: 10px; - padding: 5px; - height: 32px; + padding: 12px; + height: 30px; .right { float: right; @@ -271,7 +267,6 @@ background-color: white; border: 1px solid #ddd; margin-bottom: 10px; - @include border-radius-all(4px); } .type { color: lighten($black, 40%); diff --git a/app/assets/stylesheets/mobile/user.scss b/app/assets/stylesheets/mobile/user.scss index bfdd68e26..c0728bc03 100644 --- a/app/assets/stylesheets/mobile/user.scss +++ b/app/assets/stylesheets/mobile/user.scss @@ -47,7 +47,6 @@ width: 220px; min-height: 200px; background-color: #f8f8f8; - border-radius: 5px; color: #444; word-wrap: break-word; } @@ -56,8 +55,12 @@ h3 { color: #666; + padding-left: 5px; + } + .nav-stacked { + border-left: 0; + border-right: 0; } - .summary { height: 50px; } @@ -110,11 +113,8 @@ background-color: #444; margin-bottom: 10px; overflow: hidden; - border: 1px solid #bbb; color: #fff; - @include border-radius-all(4px); - .details { text-align: center; padding: 10px; @@ -143,7 +143,6 @@ background-color: #222; text-align: left; padding: 0 10px; - @include border-radius-all(4px); dd { color: white; @@ -159,9 +158,49 @@ .controls { background-color: #ddd; margin-top: 0px; - padding: 5px; + padding: 10px 10px 0 10px; - button { margin-bottom: 3px; } + .btn { + margin-bottom: 10px; + float: none; + } + } + } + + .about.collapsed-info { + .controls { + margin-top: 0; + } + + .details { + .secondary { display: none; } + .bio { display: none; } + + .primary { + width: 100%; + text-align: left; + margin-top: 4px; + + .avatar { + float: left; + margin-right: 10px; + border: 2px solid white; + width: 45px; + height: 45px; + } + + h1 { + margin:0; + font-size: 20px; + line-height: 22px; + } + + h2 { + font-size: 17px; + line-height: 16px; + margin-top: 4px; + } + } } } @@ -186,9 +225,7 @@ .item { padding: 10px 8px; background-color: white; - border: 1px solid #b9b9b9; - margin-bottom: 10px; - @include border-radius-all(4px); + border-bottom: 1px solid #b9b9b9; } .type { color: lighten($black, 40%); diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5a7dad77f..2a339818d 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -134,7 +134,7 @@ class ApplicationController < ActionController::Base def serialize_data(obj, serializer, opts={}) # If it's an array, apply the serializer as an each_serializer to the elements serializer_opts = {scope: guardian}.merge!(opts) - if obj.is_a?(Array) + if obj.is_a?(Array) or obj.is_a?(ActiveRecord::Associations::CollectionProxy) serializer_opts[:each_serializer] = serializer ActiveModel::ArraySerializer.new(obj, serializer_opts).as_json else diff --git a/app/jobs/scheduled/version_check.rb b/app/jobs/scheduled/version_check.rb index 91528bf7c..a50e7c2fe 100644 --- a/app/jobs/scheduled/version_check.rb +++ b/app/jobs/scheduled/version_check.rb @@ -11,6 +11,7 @@ module Jobs should_send_email = (SiteSetting.new_version_emails and DiscourseUpdates.missing_versions_count and DiscourseUpdates.missing_versions_count == 0) json = DiscourseHub.discourse_version_check + DiscourseUpdates.last_installed_version = Discourse::VERSION::STRING DiscourseUpdates.latest_version = json['latestVersion'] DiscourseUpdates.critical_updates_available = json['criticalUpdates'] DiscourseUpdates.missing_versions_count = json['missingVersionsCount'] diff --git a/app/models/discourse_version_check.rb b/app/models/discourse_version_check.rb index 00e21d04f..01a1a9d05 100644 --- a/app/models/discourse_version_check.rb +++ b/app/models/discourse_version_check.rb @@ -7,7 +7,7 @@ class DiscourseVersionCheck include ActiveModel::Serialization end - attr_accessor :latest_version, :critical_updates, :installed_version, :installed_sha, :missing_versions_count, :updated_at + attr_accessor :latest_version, :critical_updates, :installed_version, :installed_sha, :missing_versions_count, :updated_at, :version_check_pending unless rails4? def active_model_serializer diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index f51176145..619cf6831 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1090,6 +1090,7 @@ en: please_upgrade: "Please upgrade!" no_check_performed: "A check for updates has not been performed. Ensure sidekiq is running." stale_data: "A check for updates has not been performed lately. Ensure sidekiq is running." + version_check_pending: "Looks like you upgraded recently. Fantastic!" installed_version: "Installed" latest_version: "Latest" problems_found: "Some problems have been found with your installation of Discourse:" diff --git a/config/locales/client.nl.yml b/config/locales/client.nl.yml index 5e64204e5..6da8a354a 100644 --- a/config/locales/client.nl.yml +++ b/config/locales/client.nl.yml @@ -75,7 +75,7 @@ nl: other: "%{count} dagen geleden" share: topic: Deel een link naar deze topic - post: Deel een link naar dit bericht + post: "Deel een link naar bericht #%{postNumber}" close: sluit twitter: deel deze link op Twitter facebook: deel deze link op Facebook @@ -92,18 +92,28 @@ nl: log_in: Log in age: Leeftijd last_post: Laatste bericht + joined: Lid sinds admin_title: Beheer flags_title: Meldingen show_more: meer... links: Links faq: FAQ privacy_policy: "Privacy Policy" + mobile_view: Mobiele versie + desktop_versie: Desktopversie you: Jij or: of now: zonet read_more: lees verder more: Meer less: Minder + never: nooit + daily: dagelijks + weekly: wekelijks + every_two_weeks: elke twee weken + character_count: + one: "{{count}} teken" + other: "{{count}} tekens" in_n_seconds: one: "over 1 seconde" @@ -136,6 +146,10 @@ nl: saving: Wordt opgeslagen... saved: Opgeslagen! + upload: Upload + uploading: Uploaden... + uploaded: Geupload! + choose_topic: none_found: Geen topics gevonden. title: @@ -173,9 +187,21 @@ nl: "12": "Verzonden items" "13": "Inbox" + categories: + all: alle categoriëen + only_category: "only {{categoryName}}" + category: Categorie + posts: Berichten + topics: Topics + latest: Laatste + latest_by: Laatste door + toggle_ordering: schakel sorteermethode + subcategories: "Subcategoriëen:" + user: said: "{{username}} zei:" profile: Profiel + show_profile: Bekijk profiel mute: Negeer edit: Wijzig voorkeuren download_archive: download een archief van mijn berichten @@ -193,11 +219,18 @@ nl: change: verander moderator: "{{user}} is een moderator" admin: "{{user}} is een admin" + deleted: (verwijderd) + + messages: + all: Alle + mine: Mijn + unread: Ongelezen change_password: success: (e-mail verzonden) in_progress: (e-mail wordt verzonden) error: (fout) + action: Stuur wachtwoord-reset-mail change_about: title: Wijzig bio @@ -215,6 +248,15 @@ nl: error: "Het veranderen van je e-mailadres is mislukt. Wellicht is deze al in gebruik?" success: "We hebben een mail gestuurd naar dat adres. Volg de bevestigingsinstructies in die mail." + change_avatar: + title: Wijzig je avatar + gravatar: "Gravatar, gebaseerd op" + gravatar_title: Verander je avatar op Gravatars website + uploaded_avatar: Eigen afbeelding + uploaded_avatar_empty: Voeg een eigen afbeelding toe + upload_title: Upload je afbeelding + image_is_not_a_square: "Let op: we hebben je afbeelding bijgesneden omdat het geen vierkant is." + email: title: E-mail instructions: Je e-mail adres zal nooit publieklijk zichtbaar zijn. @@ -259,6 +301,7 @@ nl: email_direct: "Ontvang een mail wanneer iemand je citeert, reageert op je bericht of je @gebruikersnaam noemt." email_private_messages: Ontvang een mail wanneer iemand je een privé-bericht heeft gestuurd. + email_always: "Ontvang notificaties en topicoverzichten zelfs als ik actief ben op het forum." other_settings: Overige @@ -346,6 +389,7 @@ nl: private_message_info: title: 'Privé-bericht' invite: Nodig anderen uit... + remove_allowed_user: "Weet je zeker dat je {{name}} wil verwijderen uit deze priveconversatie?" email: E-mail username: Gebruikersnaam @@ -378,6 +422,7 @@ nl: authenticating: Authenticatie... awaiting_confirmation: "Je account is nog niet geactiveerd. Gebruik de 'Wachtwoord vergeten'-link om een nieuwe activatie-mail te ontvangen." awaiting_approval: "Je account is nog niet goedgekeurd door iemand van de staf. Je krijgt van ons een mail wanneer dat gebeurd is." + requires_invite: "Toegang tot dit forum is alleen op uitnodiging." not_activated: "Je kan nog niet inloggen. We hebben je een activatie-mail gestuurd (naar {{currentEmail}}). Het kan een aantal minuten duren voor deze aan komt. Check ook je spamfolder." resend_activation_email: Klik hier om de activatiemail opnieuw te ontvangen. sent_activation_email_again: "We hebben een nieuwe activatiemail gestuurd naar {{currentEmail}}. Het kan een aantal minuten duren voor deze aan komt. Check ook je spamfolder." @@ -453,8 +498,8 @@ nl: link_optional_text: optionele titel quote_title: Citaat quote_text: Citaat - code_title: Code voorbeeld - code_text: hier de code + code_title: Opgemaakte tekst + code_text: geef hier de opgemaakte tekst upload_title: Afbeelding upload_description: geef een omschrijving voor de afbeelding op olist_title: Genummerde lijst @@ -485,7 +530,7 @@ nl: private_message: " {{username}} {{link}}" invited_to_private_message: " {{username}} {{link}}" invitee_accepted: " {{username}} heeft je uitnodiging geaccepteerd en heeft zich ingeschreven om deel te nemen." - moved_post: " {{username}} verplaatst naar {{link}}" + moved_post: " {{username}} verplaatst {{link}}" total_flagged: aantal gemarkeerde berichten upload_selector: @@ -497,6 +542,8 @@ nl: remote_tip_with_attachments: "vul een internetadres in van een afbeelding of bestand in deze vorm: http://example.com/bestand.ext (toegestane extensies: {{authorized_extensions}})." local_tip: "klik om een afbeelding vanaf je apparaat te selecteren." local_tip_with_attachments: "klik om een afbeelding of bestand vanaf je apparaat te selecteren (toegestane extensies: {{authorized_extensions}})." + hint: "(je kan afbeeldingen ook slepen in de editor om deze te uploaden)" + hint_for_chrome: "(je kan afbeeldingen ook slepen of plakken in de editor om deze te uploaden)" uploading: Afbeelding uploaden search: @@ -545,11 +592,18 @@ nl: title: Details topic rangorde topic: + filter_to: "Laat alleen de {{post_count}} berichten van {{username}} in deze topic zien" create: Maak topic create_long: Maak een nieuw topic private_message: Stuur een privé-bericht list: Topics new: nieuw topic + new_topics: + one: 1 nieuwe topic + other: "{{count}} nieuwe topics" + unread_topics: + one: 1 ongelezen topic + other: "{{count}} ongelezen topics" title: Topic loading_more: Er worden meer topics geladen... loading: Bezig met laden van topic... @@ -607,7 +661,6 @@ nl: auto_close_notice: "Deze topic wordt automatisch over %{timeLeft} gesloten." auto_close_title: 'Instellingen voor automatisch sluiten' auto_close_save: Opslaan - auto_close_cancel: Annuleren auto_close_remove: Sluit deze topic niet automatisch progress: @@ -713,7 +766,7 @@ nl: split_topic: title: Splits topic action: splits topic - topic_name: "Naam nieuwe topic:" + topic_name: "Naam nieuwe topic" error: "Er ging iets mis bij het splitsen van die topic." instructions: one: "Je staat op het punt een nieuwe topic aan te maken en het te vullen met het bericht dat je geselecteerd hebt." @@ -730,6 +783,7 @@ nl: multi_select: select: selecteer selected: "geselecteerd ({{count}})" + select_replies: "selecteer +antwoorden" delete: verwijder geselecteerde cancel: annuleer selectie description: @@ -782,6 +836,12 @@ nl: undelete: herstel dit bericht share: deel een link naar dit bericht more: Meer + delete_replies: + confirm: + one: "Wil je ook het directe antwoord op dit bericht verwijderen?" + other: "Wil je ook de {{count}} directe antwoorden op dit bericht verwijderen?" + yes_value: "Ja, verwijder deze antwoorden ook" + no_value: "Nee, alleen dit bericht" actions: flag: 'Markeer' @@ -887,6 +947,7 @@ nl: category: can: 'can… ' none: (geen categorie) + choose: 'Selecteer een categorie…' edit: bewerk edit_long: Bewerk categorie view: Bekijk topics in categorie @@ -917,6 +978,9 @@ nl: auto_close_label: "Sluit topics automatisch na:" edit_permissions: Wijzig permissies add_permission: Nieuwe permissie + this_year: dit jaar + position: positie + parent: Bovenliggende categorie flagging: title: Waarom meld je dit bericht? @@ -924,7 +988,7 @@ nl: take_action: Onderneem actie notify_action: Meld delete_spammer: Verwijder spammer - delete_confirm: "Je gaat nu %{posts} berichten en %{topics} van deze gebruiker verwijderen, hun account verwijderen en hun e-mailadres %{email} op een permanente blokkeerlijst zetten. Weet je zeker dat dit een spammer is?" + delete_confirm: "Je gaat nu %{posts} berichten en %{topics} van deze gebruiker verwijderen, hun account verwijderen, nieuwe aanmeldingen vanaf hun IP-adres %{ip_address} blokkeren en hun e-mailadres %{email} op een permanente blokkeerlijst zetten. Weet je zeker dat dit een spammer is?" yes_delete_spammer: "Ja, verwijder spammer" cant: "Sorry, je kan dit bericht momenteel niet melden." custom_placeholder_notify_user: "Wat maakt dat je de schrijver persoonlijk iets wil melden? Wees specifiek, constructief en altijd aardig." @@ -1028,8 +1092,8 @@ nl: critical_available: Er is een belangrijke update beschikbaar updates_available: Er zijn updates beschikbaar please_upgrade: Werk de software bij alsjeblieft - no_check_performed: Er is nog niet op updates gecontroleerd. Zorgen sidekiq loopt." - stale_data: Er is al een tijdje niet op updates gecontroleerd. Zorgen sidekiq loopt." + no_check_performed: Er is nog niet op updates gecontroleerd. Zorgen dat sidekiq loopt." + stale_data: Er is al een tijdje niet op updates gecontroleerd. Zorgen dat sidekiq loopt." installed_version: Geïnstalleerd latest_version: Recent problems_found: 'Er zijn een aantal problemen gevonden met je Discourse installatie:' @@ -1110,12 +1174,18 @@ nl: delete_failed: "Unable to delete group. If this is an automatic group, it cannot be destroyed." api: + generate_master: Genereer Master API Key + none: Er zijn geen actieve API keys + user: Gebruiker title: API - long_title: "API informatie" - key: "Key" + key: API Key generate: "Genereer API Key" regenerate: "Genereer API Key opnieuw" + revoke: Intrekken + confirm_regen: Weet je zeker dat je die API Key wil vervangen door een nieuwe? + confirm_revoke: Weet je zeker dat je die API Key wil intrekken? info_html: "Met deze API key kun je met behulp van JSON calls topics maken en bewerken." + all_users: Alle gebruikers note_html: "Houd deze key geheim, gebruikers die deze key hebben kunnen zich als elke andere gebruiker voordoen op het forum en topics aanmaken." customize: @@ -1123,6 +1193,8 @@ nl: long_title: Aanpassingen aan de site header: Header css: Stylesheet + mobile_header: Mobiele header + mobile_css: Mobiele stylesheet override_default: Sluit de standaard stylesheet uit enabled: Ingeschakeld? preview: voorbeeld @@ -1174,12 +1246,44 @@ nl: clear_filters: Bekijk alles staff_user: Staflid target_user: Selecteer gebruiker + subject: Onderwerp when: Wanneer context: Context details: Details + previous_value: Vorige + new_value: Nieuw + diff: Diff + show: Bekijk + modal_title: Details + no_previous: Er is geen vorige waarde + deleted: Geen nieuwe waarde. De record was verwijderd. actions: delete_user: verwijder gebruiker change_trust_level: verander trust level + change_site_setting: verander instellingen + change_site_customization: verander site aanpassingen + delete_site_customization: verwijder site aanpassingen + ban_user: ban gebruiker + unban_user: hef ban op + screened_emails: + title: Gescreende e-mails + description: Nieuwe accounts met een van deze mailadressen worden geblokkeerd of een andere actie wordt ondernomen. + email: E-mailadres + screened_urls: + title: Gescreende urls + description: Deze urls zijn gebruikt door gebruikers die als spammer gemarkeerd zijn. + url: URL + screened_ips: + title: Gescreende ip-adressen + description: IP-adressen die in de gaten worden gehouden. Kies 'sta toe' om deze op een witte lijst te zetten. + delete_confirm: "Weet je zeker dat je de regel voor %{ip_address} wil verwijderen?" + actions: + block: Blokkeer + do_nothing: Sta toe + form: + label: "Nieuw:" + ip_address: IP-adres + add: Voeg toe impersonate: title: Log in als gebruiker @@ -1206,6 +1310,9 @@ nl: approved_selected: one: accepteer lid other: "accepteer {{count}} leden" + reject_selected: + one: weiger lid + other: "weiger {{count}} leden" titles: active: 'Actieve leden' new: 'Nieuwe leden' @@ -1219,12 +1326,23 @@ nl: moderators: Moderators blocked: Geblokkeerde leden banned: Verbannen leden + reject_successful: + one: "1 Gebruiker met succes geweigerd" + other: "%{count} Gebruikers met succes geweigerd" + reject_failures: + one: "Weigering van 1 gebruiker is niet gelukt" + other: "Weigering van %{count} gebruikers is niet gelukt" user: ban_failed: "Er ging iets fout met het blokkeren van deze gebruiker: {{error}}" unban_failed: "Er ging iets fout bij het deblokkeren van deze gebruiker: {{error}}" - ban_duration: "Hoe lang wil je deze gebruiker blokkeren? (dagen)" + ban_duration: "Hoe lang wil je deze gebruiker blokkeren?" + ban_duretion_units: (dagen) + ban_reason_label: "Waarom ban je? Als de gebruiker in probeert te loggen, zullen ze deze tekst zien. Hou het kort." + ban_reason: Reden voor ban + banned_by: Verbannen door delete_all_posts: Verwijder alle berichten + delete_all_posts_confirm: "Je gaat %{posts} en %{topics} verwijderen. Zeker weten?" ban: Blokkeer unban: Deblokkeer banned: Geblokkeerd? @@ -1263,8 +1381,8 @@ nl: one: "Gebruikers kunnen niet worden verwijders als ze zich meer dan %{count} dag geleden registreerden of als ze berichten geplaatst hebben. Verwijder alle berichten voordat je een gebruiker probeert te verwijderen." other: "Gebruikers kunnen niet worden verwijders als ze zich meer dan %{count} dagen geleden registreerden of als ze berichten geplaatst hebben. Verwijder alle berichten voordat je een gebruiker probeert te verwijderen." delete_confirm: Weet je zeker dat je deze gebruiker definitief wil verwijderen? Deze handeling is permanant! - delete_and_block: "Ja, en blokkeer registraties met datzelfde e-mailadres" - delete_dont_block: "Ja, maar sta nieuwe registraties toe met datzelfde e-mailadres" + delete_and_block: "Ja, en blokkeer registraties met datzelfde e-mail- en IP-adres" + delete_dont_block: "Ja, maar sta nieuwe registraties toe met datzelfde e-mail- en IP-adres" deleted: De gebruiker is verwijderd. delete_failed: Er ging iets mis bij het verwijderen van deze gebruiker. Zorg er voor dat alle berichten van deze gebruiker eerst verwijderd zijn. send_activation_email: Verstuur activatiemail @@ -1280,6 +1398,7 @@ nl: banned_explanation: Een verbannen gebruiker kan niet meer inloggen. block_explanation: Een geblokkeerde gebruiker kan geen topics maken of reageren op topics. trust_level_change_failed: Er ging iets mis bij het wijzigen van het trust level van deze gebruiker. + ban_modal_title: Ban gebruiker site_content: none: Selecteer een tekst om deze te bewerken diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml index edac72a3f..99d860334 100644 --- a/config/locales/server.nl.yml +++ b/config/locales/server.nl.yml @@ -97,7 +97,7 @@ nl: Voor meer informatie, [bekijk onze Veel Gestelde Vragen](/faq). Deze tekst zal alleen verschijnen bij je eerste %{education_posts_text}. 'new-reply': | - Welkom op %{site_name} — **bedankt voor het deelnemen aan de conversatie!** + Welkom op %{site_name} — **bedankt voor je bijdrage!** - Geeft je reactie een nuttige bijdrage aan de conversatie, hoe klein dan ook? @@ -107,6 +107,30 @@ nl: Voor meer informatie, [bekijk onze Veel Gestelde Vragen](/faq). Deze tekst zal alleen verschijnen bij je eerste %{education_posts_text}. + avatar: | + ### Wat dacht je van een nieuwe afbeelding voor je account? + + Je hebt een aantal berichten en reacties geplaatst, maar je avatar is niet zo uniek als jij bent -- het is dezelfde avatar als alle andere nieuwe gebruikers hebben. + + Heb je al overwogen **[om naar je profielpagina te gaan](%{profile_path})** om een nieuwe afbeelding van jou te uploaden? + + Het is makkelijker om conversaties te volgen en interessante mensen te vinden als iedereen een unieke avatar heeft! + + sequential_replies: | + ### Overweeg om op meerdere berichten ineens te reageren + + In plaatst van een reactie per bericht te plaatsten, kan je ook meerdere berichten ineens citeren en @namen noemen in je reactie. + + Je kan je vorige reactie wijzigen en er een citaat aan toevoegen door de betreffende tekst te selecteren en op de citeer knop te drukken die dan verschijnt. + + Het is voor iedereen makkelijker om topics te lezen met minder losstaande reacties. + + dominating_topic: | + ### Laat anderen meedoen in de conversatie + + Deze topic is duidelijk belangrijk voor je – meer dan %{percent}% van de reacties zijn van jou. + + Hou je in de gaten dat anderen ook de ruimte krijgen om hun visie te geven? activerecord: attributes: @@ -114,6 +138,8 @@ nl: name: Naam categorie post: raw: Inhoud + user: + ip_address: "" errors: messages: is_invalid: "is ongeldig; probeer wat uitgebreider te zijn" @@ -123,6 +149,10 @@ nl: attributes: archetype: cant_send_pm: "Sorry, je kan geen privébericht sturen naar deze persoon." + user: + attributes: + ip_address: + signup_not_allowed: Inschrijven vanaf dit account is niet toegestaan. user_profile: no_info_me: "
Het Over Mij-profielveld is nog leeg, zou je deze willen invullen?
" @@ -132,7 +162,9 @@ nl: topic_prefix: "Beschrijving voor categorie %{category}" replace_paragraph: "[Vervang deze eerste regel met een korte omschrijving van je nieuwe categorie. Deze regel verschijnt in het selectiemenu als iemand een categorie kiest, dus hou het kort (max. 200 tekens).]" post_template: "%{replace_paragraph}\n\nGebruik de volgende alinea's voor een lange omschrijving en om wat verwachtingen en regels van deze categorie uit te leggen.\n\nZaken waar je het over kan hebben in de reacties hieronder:\n\n- Waar is deze categorie voor? Waarom zouden mensen deze categorie moeten kiezen voor hun topic?\n\n- Waarin verschilt deze categorie van de andere categorien die we al hebben?\n\n- Hebben we deze categorie echt nodig?\n\n- Moeten we deze categorie samenvoegen met een andere categorie, of juist opsplitsen?\n" - + errors: + self_parent: "Een subcategorie kan niet onder zichzelf hangen." + depth: "Je kan een subcategorie niet onder een andere subcategorie hangen." trust_levels: newuser: title: nieuw lid @@ -143,7 +175,7 @@ nl: leader: title: leider elder: - title: stamoudste + title: emiritus change_failed_explanation: "Je probeerde %{user_name} te degraderen naar '%{new_trust_level}'. Echter, het trust level is al '%{current_trust_level}'. %{user_name} blijft op trust level '%{current_trust_level}'" @@ -263,7 +295,7 @@ nl: long_form: heeft dit als spam gemeld inappropriate: title: Ongepast - description: 'Dit bericht bevat inhoud dat een persoon met gezond verstand als beledigend, discriminerend of kwetsend kan ervaren.' + description: 'Dit bericht bevat inhoud dat iemand als beledigend, discriminerend of kwetsend kan ervaren. Ook kan het een overtreding van de regels zijn.' long_form: heeft dit als ongepast gemeld notify_user: title: "Licht {{username}} in" @@ -389,6 +421,7 @@ nl: dashboard: rails_env_warning: "Je server draait in %{env} modus." + ruby_version_warning: Je gebruikt een versie van Ruby 2.0.0 met problemen. Upgrade naar patch level 247 of later. host_names_warning: "Het bestand config/database.yml heeft localhost als standaard hostname. Werk dat bij naar de hostname van je site." gc_warning: 'Je server gebruikt de standaard ruby garbage collection instellingen, en daarmee krijg je niet de beste prestaties. Lees deze topic over instellingen voor prestaties: Tuning Ruby and Rails for Discourse.' sidekiq_warning: 'Sidekiq draait niet. Veel taken, zoals het versturen van e-mails, worden asynchroon uitgevoerd door sidekiq. Zorg ervoor dat er altijd een sidekiq process draait. Hier is meer informatie over sidekiq.' @@ -399,12 +432,13 @@ nl: twitter_config_warning: 'De server is geconfigureerd om registratie en inloggen via Twitter mogelijk te maken (enable_twitter_logins), maar er zijn geen key en secret waarden opgegeven. Ga naar de Instellingen en vul de waarden in. Zie deze uitleg voor meer informatie.' github_config_warning: 'De server is geconfigureerd om registratie en inloggen via Github mogelijk te maken (enable_github_logins), maar er zijn geen client id en secret waarden opgegeven. Ga naar de Instellingen en vul de waarden in. Zie deze uitleg voor meer informatie.' s3_config_warning: 'De server is geconfigureerd om bestanden naar S3 te uploaden, maar tenminste een van de volgende instellingen is niet opgegeven: s3_access_key_id, s3_secret_access_key of s3_upload_bucket. Ga naar de Instellingen en vul de waarden in. Zie "How to set up image uploads to S3?" voor meer informatie.' - image_magick_warning: 'De server is geconfigureerd om thumbnails te maken van grote afbeeldingen, maar ImageMagick is niet geïnstalleerd. Installeer ImageMagick met je favoriete package manager of ga naar om de laatste release te downloaden.' + image_magick_warning: 'De server is geconfigureerd om thumbnails te maken van grote afbeeldingen, maar ImageMagick is niet geïnstalleerd. Installeer ImageMagick met je favoriete package manager of download de laatste release.' failing_emails_warning: 'Er zijn %{num_failed_jobs} mislukte emailtaken. Check of de instellingen voor config.action_mailer in het bestand config/environments/production.rb kloppen. Bekijk alle mislukte Sidekiq jobs.' default_logo_warning: "Je hebt nog niet een eigen logo ingesteld voor je site. Werk logo_url, logo_small_url, en favicon_url bij in de Instellingen." contact_email_missing: "Je hebt nog geen contactadres opgegeven voor je site. Werk contact_email bij in de Instellingen." contact_email_invalid: "Je hebt een ongeldig contactadres opgegeven voor je site. Werk contact_email bij in de Instellingen." title_nag: "Je hebt nog geen title ingesteld voor je site. Geef een titel voor je site op in de Instellingen." + site_description_missing: "Er is nog geen omschrijving van deze site. Schrijf een korte omschrijving in de Instellingen" consumer_email_warning: "Je site is ingesteld om Gmail te gebruiken voor het versturen van mails. Gmail heeft limieten voor het aantal mails dat je kan versturen. Overweeg om een andere e-mailprovider te gebruiken om er zeker van te zijn dat mails aankomen." access_password_removal: "Je site gebruikte een toegangswachtwoord (access_password) setting, maar die optie is uit Discourse verwijderd. De login_required en must_approve_users instellingen zijn er voor in de plaats gekomen. Je kan ze in de Instellingen aanpassen. Zorg er voor dat je gebruikers op de wachtlijst accepteert. (Dit bericht verdwijnt na twee dagen.)" site_contact_username_warning: "De instelling site_contact_username is leeg. Werk deze bij in de Instellingen. Stel het in op de gebruikersnaam van een admin die als afzender van de systeemberichten zal worden wordt gebruikt." @@ -461,6 +495,7 @@ nl: discourse_org_access_key: "De toegangscode voor het discourse.org nickname-register" educate_until_posts: Laat een popup zien totdat een lid dit aantal berichten geplaatst heeft title: "Titel van deze website, wordt gebruikt in de paginatitel en elders" + site_description: Omschrijf dit forum in een zin. Deze wordt getoond in de meta tag. contact_email: E-mailadres van een contactpersoon van deze site. Belangrijke updates van Discourse.org worden naar dit adres gestuurd. company_full_name: "De volledige naam van het bedrijf dat deze site draait. Wordt gebruikt in juridische delen van de site, zoals /tos" company_short_name: "De korte naam van het bedrijf dat deze site draait. Wordt gebruikt in juridische delen van de site, zoals /tos" @@ -470,7 +505,8 @@ nl: ninja_edit_window: "Hoe snel je een aanpassing kan maken zonder dat er een nieuwe versie wordt opgeslagen, in seconden." edit_history_visible_to_public: "Iedereen mag eerdere versies van een bericht zien. Wanneer aangevinkt kan alleen de staf de eerdere versies van een bericht zien." delete_removed_posts_after: "Na dit aantal uren zal een door een gebruiker verwijderd bericht ook echt helemaal verwijderd worden (in plaats van alleen verborgen)." - max_image_width: Maximale breedte voor een afbeelding in een bericht + max_image_width: Maximale breedte van een afbeelding in een bericht + max_image_height: Maximale hoogte van een afbeelding in een bericht category_featured_topics: Aantal topics dat wordt weergegeven in de categorielijst add_rel_nofollow_to_user_content: "Voeg 'rel nofollow' toe aan alle leden-content behalve voor interne links (inclusief parent domeinen). NB: Als je dit verandert, moet je ook alle 'baked markdown' updaten met \"rake posts:rebake\"" exclude_rel_nofollow_domains: "Een kommagescheiden lijst van domeinen waar 'nofollow' niet is toegevoegd (voorbeelddomein.com zal automatisch sub.voorbeelddomein.com toestaan)." @@ -504,9 +540,14 @@ nl: flags_required_to_hide_post: "Berichten zullen automatisch worden verborgen zodra het aantal meldingen maximaal dit aantal is (0 voor nooit)" cooldown_minutes_after_hiding_posts: "Hoeveel minuten moet iemand wachten voordat zij hun bericht kunnen wijzigen nadat het is verborgen door meldingen" + + max_topics_in_first_day: "Het maximum aantal topics dat een gebruiker mag maken tijdens hun eerste dag op de site" + max_replies_in_first_day: "Het maximum aantal reacties dat een gebruiker mag schrijven tijdens hun eerste dag op de site" + num_flags_to_block_new_user: "Als de berichten van een nieuwe gebruiker dit aantal spammarkeringen krijgen van (n) verschillende gebruikers, verberg dan alle berichten van deze gebruiker en houdt nieuwe berichten tegen. 0 om deze mogelijkheid uit te zetten." num_users_to_block_new_user: "Als de berichten van een nieuwe gebruiker (x) spammarkeringen krijgen van andere gebruikers, verberg dan alle berichten van deze gebruiker en houdt nieuwe berichten tegen. 0 om deze mogelijkheid uit te zetten." - + notify_mods_when_user_blocked: "Als een gebruiker automatisch geblokkeerd is, stuur dan een bericht naar alle moderatoren." + flag_sockpuppets: "Als een nieuwe gebruiker (bijv. geregistreerd in de afgelopen 24 uur) reageert op de topic van een andere nieuwe gebruiker, maar wel van hetzelfde IP-adres dan, worden beide berichten automatisch gemarkeerd als spam." traditional_markdown_linebreaks: "Gebruik traditionele regeleinden in Markdown, gebruik 2 spaties voor een nieuw regeleinde" post_undo_action_window_mins: "Het tijdsbestek waarin iemand een actie binnen een bericht kan terugdraaien (zoals 'vind ik leuk')" @@ -530,15 +571,16 @@ nl: email_domains_blacklist: "Een lijst met e-maildomeinen gescheiden door een |-teken van domeinen die niet worden toegestaan. Voorbeeld: mailinator.com|trashmail.net" email_domains_whitelist: "Een lijst met e-maildomeinen gescheiden door een |-teken van domeinen die wel worden toegestaan. N.B.: als je hier iets opgeeft, zijn andere domeinen NIET toegestaan." version_checks: "Ping de Discourse-hub voor versieupdates and laat versiemeldingen zien in het /admin dashboard" + new_version_emails: Stuur een e-mail naar het contact-email adres als er een nieuwe versie beschikbaar is. - port: "Mocht je een specifieke poort willen toewijzen aan de URL. Handig in ontwikkelaars-modus. Laat leeg voor geen toewijzing." - force_hostname: "Mocht je een specifieke hostname willen toewijzen. Handig in ontwikkelaars-modus. Laat leeg voor geen toewijzing." + port: "DEVELOPER ONLY! WARNING! Mocht je een specifieke poort willen toewijzen aan de URL. Handig in ontwikkelaars-modus. Laat leeg voor geen toewijzing." + force_hostname: "DEVELOPER ONLY! WARNING! Mocht je een specifieke hostname willen toewijzen. Handig in ontwikkelaars-modus. Laat leeg voor geen toewijzing." invite_expiry_days: "Hoe lang uitnodigingscodes geldig blijven (in dagen)." # TODO: perhaps we need a way of protecting these settings for hosted solution, global settings ... - invite_only: "Registratie is gesloten, alleen toegang op uitnodiging." + invite_only: "Registratie is niet mogelijk, alleen toegang op uitnodiging." login_required: Inloggen vereist om berichten te kunnen lezen @@ -583,6 +625,8 @@ nl: suggested_topics: Het aantal aanbevolen topics dat is weergegeven aan de onderkant van een topic + clean_up_uploads: "Verwijder weesbestanden om illegale hosting te voorkomen. LET OP: maak een backup van je /uploads directory voordat je deze instelling activeert." + uploads_grace_period_in_hours: Na hoeveel uur een weesbestand verwijderd wordt. enable_s3_uploads: Of we uploads op Amazon S3 willen zetten of niet s3_upload_bucket: "De 'bucket' waarin we onze uploads naar Amazon S3 willen zetten" s3_access_key_id: "De Amazon S3 access key id dat wordt gebruikt om afbeeldingen te uploaden" @@ -606,6 +650,8 @@ nl: regular_requires_likes_given: "Hoeveel keer een nieuw lid berichten leuk moet vinden voordat hij gepromoveerd wordt tot regulier lid (trust level 2)" regular_requires_topic_reply_count: "Op hoeveel topics een nieuw lid moet reageren voordat hij gepromoveerd wordt tot regulier lid (trust level 2)" + min_trust_to_create_topic: "Het minimale trust level dat nodig is om een topic te mogen maken." + newuser_max_links: Hoeveel links een nieuw lid in een bericht kan plaatsen newuser_max_images: Hoeveel afbeeldingen een nieuw lid in een bericht kan plaatsen newuser_max_images: Hoeveel bestanden een nieuw lid in een bericht kan plaatsen @@ -627,6 +673,8 @@ nl: min_body_similar_length: De minimale lengte die de inhoud van een bericht moet hebben voordat er wordt gezocht naar vergelijkbare topics category_colors: "Een lijst, gescheiden door een pipe (|), van hexadecimal kleurwaardes die gebruikt kunnen worden voor categorien" + enable_wide_category_list: "Activeer traditionele volle breedte, non-tiling, categorielijst" + max_image_size_kb: "De maximale afbeeldingsgrootte die we toestaan voor uploads, in kB. Zorg er voor dat deze limiet ook ingesteld is in nginx (client_max_body_size) / apache of een proxy." max_attachment_size_kb: "De maximale bestandsgrootte die we toestaan voor uploads, in kB. Zorg er voor dat deze limiet ook ingesteld is in nginx (client_max_body_size) / apache of een proxy." authorized_extensions: "Een met pipes (|) gescheiden lijst van bestandsextensies die mogen worden geupload" @@ -659,9 +707,24 @@ nl: relative_date_duration: "Na hoeveel dagen de datum van een bericht relatief zijn in plaats van absoluut.Voorbeelden: relatieve datum: 7d, absolute datum: 20 feb" delete_user_max_age: "Na hoeveel dagen na de inschrijving mag een admin een gebruiker nog verwijderen." delete_all_posts_max: "Het maximaal aantal berichten dat ineens verwijderd kan worden met de 'Verwijder alle berichten'-knop. Als een gebruiker meer berichten heeft, kunnen de berichten niet in een keer verwijderd worden en kan de gebruiker dus niet verwijderd worden." - username_change_period: "The number of days after registration that accounts can change their username." + username_change_period: "The number of days after registration that accounts can change their username (0 om wijziging niet toe te staan)." + email_editable: Gebruikers mogen hun e-mailadres na registratie nog wijzigen. allow_uploaded_avatars: "Sta toe dat avatars geupload kunnen worden" + allow_animated_avatars: "Gebruikers mogen een animated GIF gebruiken als avatar. LET OP: draai de rake task avatars:regenerate nadat je deze instelling hebt geactiveerd." + default_digest_email_frequency: "Hoe vaak ontvangen gebruikers standaard de digestmails. Ze kunnen dit in hun eigen instellingen nog aanpassen." + + detect_custom_avatars: "Check of gebruikers een eigen avatar geupload hebben" + max_daily_gravatar_crawls: "Het maximum aantal keren per dag dat Discourse checkt of er nieuwe Gravatars zijn" + + sequential_replies_threshold: "Het aantal reacties dat een gebruiker achter elkaar moet plaatsen in een topic om een melding te krijgen" + + enable_mobile_theme: "Mobiele apparaten gebruiken een mobiel-vriendelijke theme met de mogelijkheid te schakelen naar de volledige site. Schakel deze optie uit als je een eigen stylesheet wil gebruiken die volledig responsive is." + + dominating_topic_minimum_percent: "Vanaf welk percentage berichten dat een gebruiker plaatst in een topic vinden we de gebruiker dominant?" + + enable_names: "Gebruikers mogen hun volledige naam laten zien" + display_name_on_posts: "Laat de volledige naam van een gebruiker ook bij zijn berichten zien" notification_types: mentioned: "%{display_username} heeft je genoemd in %{link}" @@ -717,6 +780,7 @@ nl: activate_email: "Je bent er bijna! We hebben een activatiemail verstuurd naar %{email}. Volg de instructies in de mail om je account te activeren." not_activated: "Je kan nog niet inloggen. We hebben je een activatiemail gestuurd. Volg de instructies in de mail om je account te activeren." banned: "Je kan tot %{date} niet inloggen." + banned_with_reason: "Je kan tot %{date} niet inloggen. Je hebt een ban om de volgende reden: %{reden}" errors: "%{errors}" not_available: "Niet beschikbaar. Probeer %{suggestion}?" something_already_taken: "Er ging iets mis, misschien zijn de gebruikersnaam en/of e-mailadres al in gebruik? Gebruik dan de 'wachtwoord vergeten' link" @@ -727,13 +791,15 @@ nl: username: short: "moet langer zijn dan %{min} tekens" long: "moet korter zijn dan %{max} tekens" - characters: "mag alleen nummers en letters bevatten" - unique: "moet uniek zijn" - blank: "mag niet leeg zijn" + characters: mag alleen nummers en letters bevatten + unique: moet uniek zijn + blank: mag niet leeg zijn must_begin_with_alphanumeric: "moet met een letter of nummer beginnen" email: not_allowed: "is niet toegestaan vanaf die e-mailprovider. Gebruik een ander e-mailadres." - blocked: "is niet toegestaan." + blocked: is niet toegestaan. + ip_address: + blocked: is geblokkeerd. invite_mailer: subject_template: "[%{site_name}] %{invitee_name} heeft je uitgenodigd om op een privé-bericht te reageren op %{site_name}" @@ -791,6 +857,17 @@ nl: Er zou een unsubscribe footer op elke email die je verstuurt moeten zitten zodat men direct kan afmelden mocht men deze mails niet willen ontvangen. Dus laten we er eentje opzetten! + new_version_mailer: + subject_template: "[%{site_name}] Nieuwe updates beschikbaar" + text_body_template: | + Er is een nieuwe versie van Discourse beschikbaar. + + **Nieuwe versie: %{new_version}** + + Jouw versie: %{installed_version} + + Werk zo snel mogelijk bij om de laatste oplossingen in mogelijkheden te krijgen. + system_messages: post_hidden: subject_template: "Bericht van %{site_name}: je bericht is verborgen wegens meldingen uit de community" @@ -912,19 +989,23 @@ nl: Kijk voor verdere uitleg in de [FAQ](%{base_url}/faq). user_automatically_blocked: - subject_template: "Nieuwe gebruiker %{username} was automatisch geblokkeerd" + subject_template: "Nieuwe gebruiker %{username} is door meldingen geblokkeerd" text_body_template: | - Dit is een automatisch bericht om je te informeren dat de nieuwe gebruiker [%{username}](%{user_url}) automatisch geblokkeerd is, omdat meerdere gebruikers de berichten van %{username} gemarkeerd hebben. + Dit is een automatisch bericht om je te informeren dat de nieuwe gebruiker [%{username}](%{base_url}%{user_url}) automatisch geblokkeerd is, omdat meerdere gebruikers de berichten van %{username} gemarkeerd hebben. Kijk hier voor [de markeringen](/admin/flags). Als %{username} ten onrechte geblokkeerd is, klik dan op de deblokkeerdknop op [de beheerpagina van deze gebruiker](%{user_url}). + De drempel hiervoor kan ingesteld worden met de `block_new_user` instelling. + spam_post_blocked: - subject_template: "Spam gedetecteerd in een bericht van %{username}" + subject_template: "Berichten van nieuwe gebruiker %{username} geblokkeerd door herhaalde links" text_body_template: | - Dit is een automatisch bericht van %{site_name} om je te informeren dat [%{username}](%{user_url}) probeerde een bericht te plaatsen met links, maar gebaseerd op newuser_spam_host_threshold is dit gezien als spam. + Dit is een automatisch bericht van %{site_name} om je te informeren dat de nieuwe gebruiker [%{username}](%{base_url}%{user_url}) probeerde meerdere berichten te plaatsen met links naar %{domains}, maar deze berichten zijn geblokkeerd om spam tegen te gaan. De gebruiker kan nog steeds nieuwe berichten plaatsen die niet linken naar %{domains}. Bekijk de gebruiker [hier](%{user_url}). + De drempel hiervoor kan ingesteld worden met de `newuser_spam_host_threshold` instelling. + unblocked: subject_template: Account gedeblokkeerd text_body_template: | @@ -934,6 +1015,15 @@ nl: Je kunt weer berichten plaatsen + pending_users_reminder: + subject_template: + one: "1 gebruiker wacht op goedkeuring" + other: "%{count} gebruikers wachten op goedkeuring" + text_body_template: | + Er zijn nieuwe gebruikers die zich hebben ingeschreven en wachten op goedkeuring (of afwijzing) voor zij het forum op kunnen. + + [Beoordeel deze gebruikers in het admingedeelte](/admin/users/list/pending). + unsubscribe_link: "Om deze e-mails niet langer willen ontvangen, ga naar [je gebruikersinstellingen](%{user_preferences_url})." user_notifications: @@ -1000,7 +1090,7 @@ nl: new_activity: "Nieuwe reacties op je topics en berichten:" top_topics: "Veel besproken topics:" new_topics: "Nieuwe topics:" - unsubscribe: "Deze samenvatting wordt door %{site_link} verstuurd als we je 7 dagen hebben gemist op onze site.\nMocht je dit uit willen zetten, of je e-mailvoorkeur willen veranderen, %{unsubscribe_link}." + unsubscribe: "Deze samenvatting wordt door %{site_link} verstuurd als we je 7 dagen hebben gemist op onze site. Mocht je dit uit willen zetten, of je e-mailvoorkeur willen veranderen, %{unsubscribe_link}." click_here: klik hier from: "%{site_name} Digest" read_more: Lees verder @@ -1083,3 +1173,7 @@ nl: fetch_failure: "Er ging iets mis bij het opvragen van de afbeelding." unknown_image_type: "Het bestand dat je wil uploaden is geen afbeelding." size_not_found: "Het is niet gelukt de afmetingen van de afbeelding te bepalen. Misschien is het bestand corrupt?" + + flag_reason: + sockpuppet: "Een nieuwe gebruiker maakte een nieuwe topic en een andere gebruiker reageerde - vanaf hetzelfde IP-adres. Zie de flag_sockpuppets instelling." + spam_hosts: "Deze gebruiker probeerde om meerdere berichten met links naar hetzelfde domein te plaatsen. Zie de newuser_spam_host_threshold instelling." diff --git a/lib/discourse_updates.rb b/lib/discourse_updates.rb index 918c6d1c8..250e2f897 100644 --- a/lib/discourse_updates.rb +++ b/lib/discourse_updates.rb @@ -24,20 +24,27 @@ module DiscourseUpdates # Handle cases when version check data is old so we report something that makes sense - if (version_info.updated_at.nil? or - (version_info.missing_versions_count == 0 and version_info.latest_version != version_info.installed_version) or - (version_info.missing_versions_count != 0 and version_info.latest_version == version_info.installed_version)) + if (version_info.updated_at.nil? or # never performed a version check + last_installed_version != Discourse::VERSION::STRING or # upgraded since the last version check + (version_info.missing_versions_count == 0 and version_info.latest_version != version_info.installed_version) or # old data + (version_info.missing_versions_count != 0 and version_info.latest_version == version_info.installed_version)) # old data Jobs.enqueue(:version_check, all_sites: true) - end - - if !version_info.updated_at.nil? and version_info.latest_version == version_info.installed_version - version_info.missing_versions_count = 0 + version_info.version_check_pending = true + unless version_info.updated_at.nil? + version_info.missing_versions_count = 0 + version_info.critical_updates = false + end end end version_info end + # last_installed_version is the installed version at the time of the last version check + def last_installed_version + $redis.get last_installed_version_key + end + def latest_version $redis.get latest_version_key end @@ -59,7 +66,7 @@ module DiscourseUpdates $redis.set updated_at_key, time_with_zone.as_json end - ['latest_version', 'missing_versions_count', 'critical_updates_available'].each do |name| + ['last_installed_version', 'latest_version', 'missing_versions_count', 'critical_updates_available'].each do |name| eval "define_method :#{name}= do |arg| $redis.set #{name}_key, arg end" @@ -68,6 +75,10 @@ module DiscourseUpdates private + def last_installed_version_key + 'last_installed_version' + end + def latest_version_key 'discourse_latest_version' end diff --git a/spec/components/discourse_updates_spec.rb b/spec/components/discourse_updates_spec.rb index 7e4e96ce8..f3d36e153 100644 --- a/spec/components/discourse_updates_spec.rb +++ b/spec/components/discourse_updates_spec.rb @@ -16,75 +16,103 @@ describe DiscourseUpdates do subject { DiscourseUpdates.check_version.as_json } - context 'a good version check request happened recently' do - context 'and server is up-to-date' do - before { stub_data(Discourse::VERSION::STRING, 0, false, 12.hours.ago) } + context 'version check was done at the current installed version' do + before do + DiscourseUpdates.stubs(:last_installed_version).returns(Discourse::VERSION::STRING) + end - it 'returns all the version fields' do - subject['latest_version'].should == Discourse::VERSION::STRING - subject['missing_versions_count'].should == 0 - subject['critical_updates'].should == false + context 'a good version check request happened recently' do + context 'and server is up-to-date' do + before { stub_data(Discourse::VERSION::STRING, 0, false, 12.hours.ago) } + + it 'returns all the version fields' do + subject['latest_version'].should == Discourse::VERSION::STRING + subject['missing_versions_count'].should == 0 + subject['critical_updates'].should == false + subject['installed_version'].should == Discourse::VERSION::STRING + end + + it 'returns the timestamp of the last version check' do + subject['updated_at'].should be_within_one_second_of(12.hours.ago) + end + end + + context 'and server is not up-to-date' do + before { stub_data('0.9.0', 2, false, 12.hours.ago) } + + it 'returns all the version fields' do + subject['latest_version'].should == '0.9.0' + subject['missing_versions_count'].should == 2 + subject['critical_updates'].should == false + subject['installed_version'].should == Discourse::VERSION::STRING + end + + it 'returns the timestamp of the last version check' do + subject['updated_at'].should be_within_one_second_of(12.hours.ago) + end + end + end + + context 'a version check has never been performed' do + before { stub_data(nil, nil, false, nil) } + + it 'returns the installed version' do subject['installed_version'].should == Discourse::VERSION::STRING end - it 'returns the timestamp of the last version check' do - subject['updated_at'].should be_within_one_second_of(12.hours.ago) + it 'indicates that version check has not been performed' do + subject.should have_key('updated_at') + subject['updated_at'].should == nil + end + + it 'does not return latest version info' do + subject.should_not have_key('latest_version') + subject.should_not have_key('missing_versions_count') + subject.should_not have_key('critical_updates') + end + + it 'queues a version check' do + Jobs.expects(:enqueue).with(:version_check, anything) + subject end end - context 'and server is not up-to-date' do - before { stub_data('0.9.0', 2, false, 12.hours.ago) } + # These cases should never happen anymore, but keep the specs to be sure + # they're handled in a sane way. + context 'old version check data' do + shared_examples "queue version check and report that version is ok" do + it 'queues a version check' do + Jobs.expects(:enqueue).with(:version_check, anything) + subject + end - it 'returns all the version fields' do - subject['latest_version'].should == '0.9.0' - subject['missing_versions_count'].should == 2 - subject['critical_updates'].should == false - subject['installed_version'].should == Discourse::VERSION::STRING + it 'reports 0 missing versions' do + subject['missing_versions_count'].should == 0 + end + + it 'reports that a version check will be run soon' do + subject['version_check_pending'].should == true + end end - it 'returns the timestamp of the last version check' do - subject['updated_at'].should be_within_one_second_of(12.hours.ago) + context 'installed is latest' do + before { stub_data(Discourse::VERSION::STRING, 1, false, 8.hours.ago) } + include_examples "queue version check and report that version is ok" + end + + context 'installed does not match latest version, but missing_versions_count is 0' do + before { stub_data('0.10.10.123', 0, false, 8.hours.ago) } + include_examples "queue version check and report that version is ok" end end end - context 'a version check has never been performed' do - before { stub_data(nil, nil, false, nil) } - - it 'returns the installed version' do - subject['installed_version'].should == Discourse::VERSION::STRING + context 'version check was done at a different installed version' do + before do + DiscourseUpdates.stubs(:last_installed_version).returns('0.9.1') end - it 'indicates that version check has not been performed' do - subject.should have_key('updated_at') - subject['updated_at'].should == nil - end - - it 'does not return latest version info' do - subject.should_not have_key('latest_version') - subject.should_not have_key('missing_versions_count') - subject.should_not have_key('critical_updates') - end - - it 'queues a version check' do - Jobs.expects(:enqueue).with(:version_check, anything) - subject - end - end - - context 'installed version is newer' do - before { stub_data('0.9.3', 0, false, 28.hours.ago) } - - it 'queues a version check' do - Jobs.expects(:enqueue).with(:version_check, anything) - subject - end - end - - context 'old version check data' do - context 'installed is latest' do - before { stub_data(Discourse::VERSION::STRING, 1, false, 8.hours.ago) } - + shared_examples "when last_installed_version is old" do it 'queues a version check' do Jobs.expects(:enqueue).with(:version_check, anything) subject @@ -93,16 +121,20 @@ describe DiscourseUpdates do it 'reports 0 missing versions' do subject['missing_versions_count'].should == 0 end - end - context 'installed is not latest' do - before { stub_data('0.9.1', 0, false, 8.hours.ago) } - - it 'queues a version check' do - Jobs.expects(:enqueue).with(:version_check, anything) - subject + it 'reports that a version check will be run soon' do + subject['version_check_pending'].should == true end end - end + context 'missing_versions_count is 0' do + before { stub_data('0.9.7', 0, false, 8.hours.ago) } + include_examples "when last_installed_version is old" + end + + context 'missing_versions_count is not 0' do + before { stub_data('0.9.7', 1, false, 8.hours.ago) } + include_examples "when last_installed_version is old" + end + end end diff --git a/spec/controllers/admin/versions_controller_spec.rb b/spec/controllers/admin/versions_controller_spec.rb index 13e0cad7b..364c5503a 100644 --- a/spec/controllers/admin/versions_controller_spec.rb +++ b/spec/controllers/admin/versions_controller_spec.rb @@ -4,6 +4,7 @@ require_dependency 'version' describe Admin::VersionsController do before do + Jobs::VersionCheck.any_instance.stubs(:execute).returns(true) DiscourseUpdates.stubs(:updated_at).returns(2.hours.ago) DiscourseUpdates.stubs(:latest_version).returns('1.2.33') DiscourseUpdates.stubs(:critical_updates_available?).returns(false) diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 609242792..d5d2a24f0 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -824,41 +824,84 @@ describe UsersController do end - describe '.update' do - - context 'not logged in' do - it 'raises an error when not logged in' do + describe '#update' do + context 'with guest' do + it 'raises an error' do expect do - xhr :put, :update, username: 'somename' + xhr :put, :update, username: 'guest' end.to raise_error(Discourse::NotLoggedIn) end end - context 'logged in' do - let!(:user) { log_in } + context 'with authenticated user' do + context 'with permission to update' do + it 'allows the update' do + user = Fabricate(:user, name: 'Billy Bob') + log_in_user(user) - context 'without a token' do - it 'should ensure you can update the user' do - Guardian.any_instance.expects(:can_edit?).with(user).returns(false) - put :update, username: user.username - response.should be_forbidden + put :update, username: user.username, name: 'Jim Tom' + + expect(response).to be_success + expect(user.reload.name).to eq 'Jim Tom' end - context 'as a user who can edit the user' do + it 'returns user JSON' do + user = log_in - before do - put :update, username: user.username, bio_raw: 'brand new bio' - user.reload - end + put :update, username: user.username - it 'updates the user' do - user.bio_raw.should == 'brand new bio' - end + json = JSON.parse(response.body) + expect(json['user']['id']).to eq user.id + end - it 'returns json success' do - response.should be_success + context 'when website includes http' do + it 'does not add http before updating' do + user = log_in + + put :update, username: user.username, website: 'http://example.com' + + expect(user.reload.website).to eq 'http://example.com' end end + + context 'when website does not include http' do + it 'adds http before updating' do + user = log_in + + put :update, username: user.username, website: 'example.com' + + expect(user.reload.website).to eq 'http://example.com' + end + end + end + + context 'without permission to update any attributes' do + it 'does not allow the update' do + user = Fabricate(:user, name: 'Billy Bob') + log_in_user(user) + guardian = Guardian.new(user) + guardian.stubs(:ensure_can_edit!).with(user).raises(Discourse::InvalidAccess.new) + Guardian.stubs(new: guardian).with(user) + + put :update, username: user.username, name: 'Jim Tom' + + expect(response).to be_forbidden + expect(user.reload.name).not_to eq 'Jim Tom' + end + end + + context 'without permission to update title' do + it 'does not allow the user to update their title' do + user = Fabricate(:user, title: 'Emperor') + log_in_user(user) + guardian = Guardian.new(user) + guardian.stubs(can_grant_title?: false).with(user) + Guardian.stubs(new: guardian).with(user) + + put :update, username: user.username, title: 'Minion' + + expect(user.reload.title).not_to eq 'Minion' + end end end end @@ -1102,5 +1145,4 @@ describe UsersController do end end - end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5d9db3851..e95bab803 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -77,8 +77,6 @@ Spork.prefork do config.before(:all) do DiscoursePluginRegistry.clear - uncat_id = SiteSetting.uncategorized_category_id - Discourse.current_user_provider = TestCurrentUserProvider # a bit odd, but this setting is actually preloaded diff --git a/test/javascripts/models/version_check_test.js b/test/javascripts/models/version_check_test.js index 4b6d2b57e..b03102a53 100644 --- a/test/javascripts/models/version_check_test.js +++ b/test/javascripts/models/version_check_test.js @@ -7,6 +7,7 @@ test('dataIsOld', function() { dataIsOld({updated_at: moment().subtract('hours', 2).toJSON()}, false, '2 hours ago'); dataIsOld({updated_at: moment().subtract('hours', 49).toJSON()}, true, '49 hours ago'); + dataIsOld({updated_at: moment().subtract('hours', 2).toJSON(), version_check_pending: true}, true, 'version check pending'); }); test('staleData', function() { @@ -21,4 +22,5 @@ test('staleData', function() { staleData({missing_versions_count: 0, installed_version: '0.9.4', latest_version: '0.9.3', updated_at: updatedAt(2)}, true, 'installed and latest do not match, but missing_versions_count is 0'); staleData({missing_versions_count: 1, installed_version: '0.9.3', latest_version: '0.9.3', updated_at: updatedAt(2)}, true, 'installed and latest match, but missing_versions_count is not 0'); staleData({missing_versions_count: 0, installed_version: '0.9.3', latest_version: '0.9.3', updated_at: updatedAt(50)}, true, 'old version check data'); + staleData({version_check_pending: true, missing_versions_count: 0, installed_version: '0.9.4', latest_version: '0.9.3', updated_at: updatedAt(2)}, true, 'version was upgraded, but no version check has been done since the upgrade'); }); diff --git a/vendor/gems/discourse_emoji/vendor/assets/javascripts/discourse_emoji.js b/vendor/gems/discourse_emoji/vendor/assets/javascripts/discourse_emoji.js index 394138c5c..c2a2cfac7 100644 --- a/vendor/gems/discourse_emoji/vendor/assets/javascripts/discourse_emoji.js +++ b/vendor/gems/discourse_emoji/vendor/assets/javascripts/discourse_emoji.js @@ -37,20 +37,19 @@ ":-$" : 'blush' }; - Object.keys(translations).forEach(function (code) { + emoji.forEach(function (e) { + Discourse.Dialect.inlineReplace(":" + e + ":", function(code) { + return imageFor(e); + }); + }); + Object.keys(translations).forEach(function (code) { var replacement = translations[code]; Discourse.Dialect.inlineReplace(code, function (code) { return imageFor(replacement); }); }); - Discourse.Dialect.inlineBetween({ - between: ':', - rawContents: true, - emitter: imageFor - }); - if (Discourse && Discourse.ComposerView) { Discourse.ComposerView.on("initWmdEditor", function(event){