Version bump

This commit is contained in:
Neil Lalonde 2017-10-06 11:29:02 -04:00
commit 5f0249f4ec
195 changed files with 2993 additions and 1029 deletions

View File

@ -55,7 +55,7 @@ gem 'fast_xor'
# Forked until https://github.com/sdsykes/fastimage/pull/93 is merged
gem 'discourse_fastimage', require: 'fastimage'
gem 'aws-sdk', require: false
gem 'aws-sdk-s3', require: false
gem 'excon', require: false
gem 'unf', require: false

View File

@ -1,37 +1,37 @@
GEM
remote: https://rubygems.org/
specs:
actionmailer (5.1.3)
actionpack (= 5.1.3)
actionview (= 5.1.3)
activejob (= 5.1.3)
actionmailer (5.1.4)
actionpack (= 5.1.4)
actionview (= 5.1.4)
activejob (= 5.1.4)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.1.3)
actionview (= 5.1.3)
activesupport (= 5.1.3)
actionpack (5.1.4)
actionview (= 5.1.4)
activesupport (= 5.1.4)
rack (~> 2.0)
rack-test (~> 0.6.3)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.1.3)
activesupport (= 5.1.3)
actionview (5.1.4)
activesupport (= 5.1.4)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
active_model_serializers (0.8.3)
activemodel (>= 3.0)
activejob (5.1.3)
activesupport (= 5.1.3)
activejob (5.1.4)
activesupport (= 5.1.4)
globalid (>= 0.3.6)
activemodel (5.1.3)
activesupport (= 5.1.3)
activerecord (5.1.3)
activemodel (= 5.1.3)
activesupport (= 5.1.3)
activemodel (5.1.4)
activesupport (= 5.1.4)
activerecord (5.1.4)
activemodel (= 5.1.4)
activesupport (= 5.1.4)
arel (~> 8.0)
activesupport (5.1.3)
activesupport (5.1.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (~> 0.7)
minitest (~> 5.1)
@ -44,12 +44,19 @@ GEM
ansi (1.5.0)
arel (8.0.0)
ast (2.3.0)
aws-sdk (2.5.3)
aws-sdk-resources (= 2.5.3)
aws-sdk-core (2.5.3)
aws-partitions (1.24.0)
aws-sdk-core (3.6.0)
aws-partitions (~> 1.0)
aws-sigv4 (~> 1.0)
jmespath (~> 1.0)
aws-sdk-resources (2.5.3)
aws-sdk-core (= 2.5.3)
aws-sdk-kms (1.2.0)
aws-sdk-core (~> 3)
aws-sigv4 (~> 1.0)
aws-sdk-s3 (1.4.0)
aws-sdk-core (~> 3)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.0)
aws-sigv4 (1.0.2)
barber (0.11.2)
ember-source (>= 1.0, < 3)
execjs (>= 1.2, < 3)
@ -144,13 +151,14 @@ GEM
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
logster (1.2.7)
loofah (2.0.3)
loofah (2.1.1)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
lru_redux (1.1.0)
mail (2.6.6)
mime-types (>= 1.16, < 4)
memory_profiler (0.9.8)
message_bus (2.0.5)
message_bus (2.0.8)
rack (>= 1.1.3)
metaclass (0.0.4)
method_source (0.8.2)
@ -250,8 +258,8 @@ GEM
ruby-openid (>= 2.1.8)
rack-protection (2.0.0)
rack
rack-test (0.6.3)
rack (>= 1.0)
rack-test (0.7.0)
rack (>= 1.0, < 3)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
@ -260,16 +268,16 @@ GEM
rails_multisite (1.1.0.rc4)
activerecord (> 4.2, < 6)
railties (> 4.2, < 6)
railties (5.1.3)
actionpack (= 5.1.3)
activesupport (= 5.1.3)
railties (5.1.4)
actionpack (= 5.1.4)
activesupport (= 5.1.4)
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rainbow (2.2.2)
rake
raindrops (0.18.0)
rake (12.0.0)
rake (12.1.0)
rake-compiler (1.0.4)
rake
rb-fsevent (0.9.8)
@ -279,7 +287,7 @@ GEM
ffi (>= 1.0.6)
msgpack (>= 0.4.3)
trollop (>= 1.16.2)
redis (3.3.3)
redis (3.3.5)
redis-namespace (1.5.3)
redis (~> 3.0, >= 3.0.4)
rinku (2.0.2)
@ -344,11 +352,11 @@ GEM
shoulda-context (1.2.2)
shoulda-matchers (2.8.0)
activesupport (>= 3.0.0)
sidekiq (5.0.4)
sidekiq (5.0.5)
concurrent-ruby (~> 1.0)
connection_pool (~> 2.2, >= 2.2.0)
rack-protection (>= 1.5.0)
redis (~> 3.3, >= 3.3.3)
redis (>= 3.3.4, < 5)
simple-rss (1.3.1)
slop (3.6.0)
sprockets (3.7.1)
@ -392,7 +400,7 @@ DEPENDENCIES
activerecord (~> 5.1)
activesupport (~> 5.1)
annotate
aws-sdk
aws-sdk-s3
barber
better_errors
binding_of_caller

View File

@ -103,7 +103,7 @@
{{/if}}
<div>
<label for="primary_group">
<label>
{{input type="checkbox" checked=model.primary_group}}
{{i18n 'admin.groups.primary_group'}}
</label>

View File

@ -7,6 +7,7 @@
{{future-date-input
class="suspend-until"
label="admin.user.suspend_duration"
includeForever=true
input=suspendUntil}}
</label>
</div>

View File

@ -307,7 +307,9 @@
<div class='value'>
{{i18n-yes-no model.isSuspended}}
{{#if model.isSuspended}}
{{i18n "admin.user.suspended_until" until=model.suspendedTillDate}}
{{#unless model.suspendedForever}}
{{i18n "admin.user.suspended_until" until=model.suspendedTillDate}}
{{/unless}}
{{/if}}
</div>
<div class='controls'>

View File

@ -9,6 +9,8 @@ const REPLACEMENTS = {
'd-watching-first': 'dot-circle-o',
'd-drop-expanded': 'caret-down',
'd-drop-collapsed': 'caret-right',
'd-unliked': 'heart',
'd-liked': 'heart',
'notification.mentioned': "at",
'notification.group_mentioned': "at",
'notification.quoted': "quote-right",
@ -40,7 +42,7 @@ export function renderIcon(renderType, id, params) {
let rendererForType = renderer[renderType];
if (rendererForType) {
let result = rendererForType(id, params || {});
let result = rendererForType(REPLACEMENTS[id] || id, params || {});
if (result) {
return result;
}
@ -80,8 +82,6 @@ registerIconRenderer({
name: 'font-awesome',
string(id, params) {
id = REPLACEMENTS[id] || id;
let tagName = params.tagName || 'i';
let html = `<${tagName} class='${faClasses(id, params)}'`;
if (params.title) { html += ` title='${I18n.t(params.title)}'`; }
@ -94,8 +94,6 @@ registerIconRenderer({
},
node(id, params) {
id = REPLACEMENTS[id] || id;
let tagName = params.tagName || 'i';
const properties = {

View File

@ -85,7 +85,11 @@ export default Ember.Component.extend({
const $input = this.$('.d-editor-input');
$input.autocomplete({
template: findRawTemplate('user-selector-autocomplete'),
dataSource: term => userSearch({ term, topicId, includeGroups: true }),
dataSource: term => userSearch({
term,
topicId,
includeMentionableGroups: true
}),
key: "@",
transformComplete: v => v.username || v.name
});

View File

@ -1,10 +1,7 @@
/*global Mousetrap:true */
import { default as computed, on, observes } from 'ember-addons/ember-computed-decorators';
import Category from 'discourse/models/category';
import { categoryHashtagTriggerRule } from 'discourse/lib/category-hashtags';
import { TAG_HASHTAG_POSTFIX } from 'discourse/lib/tag-hashtags';
import { search as searchCategoryTag } from 'discourse/lib/category-tag-search';
import { SEPARATOR } from 'discourse/lib/category-hashtags';
import { cookAsync } from 'discourse/lib/text';
import { translations } from 'pretty-text/emoji/data';
import { emojiSearch, isSkinTonableEmoji } from 'pretty-text/emoji';
@ -322,11 +319,7 @@ export default Ember.Component.extend({
template: findRawTemplate('category-tag-autocomplete'),
key: '#',
transformComplete(obj) {
if (obj.model) {
return Category.slugFor(obj.model, SEPARATOR);
} else {
return `${obj.text}${TAG_HASHTAG_POSTFIX}`;
}
return obj.text;
},
dataSource(term) {
return searchCategoryTag(term, siteSettings);

View File

@ -99,7 +99,6 @@ export default Ember.Component.extend(AddArchetypeClass, Scrolling, {
// this happens after route exit, stuff could have trickled in
this.appEvents.trigger('header:hide-topic');
this.appEvents.off('post:highlight');
},
@observes('Discourse.hasFocus')

View File

@ -0,0 +1,50 @@
import { default as computed, observes, on } from "ember-addons/ember-computed-decorators";
import {
PUBLISH_TO_CATEGORY_STATUS_TYPE,
OPEN_STATUS_TYPE,
DELETE_STATUS_TYPE,
REMINDER_TYPE,
CLOSE_STATUS_TYPE
} from 'discourse/controllers/edit-topic-timer';
export default Ember.Component.extend({
selection: Ember.computed.alias('topicTimer.status_type'),
autoOpen: Ember.computed.equal('selection', OPEN_STATUS_TYPE),
autoClose: Ember.computed.equal('selection', CLOSE_STATUS_TYPE),
autoDelete: Ember.computed.equal('selection', DELETE_STATUS_TYPE),
publishToCategory: Ember.computed.equal('selection', PUBLISH_TO_CATEGORY_STATUS_TYPE),
reminder: Ember.computed.equal('selection', REMINDER_TYPE),
showTimeOnly: Ember.computed.or('autoOpen', 'autoDelete', 'reminder'),
@computed('topicTimer.updateTime', 'loading', 'publishToCategory', 'topicTimer.category_id')
saveDisabled(updateTime, loading, publishToCategory, topicTimerCategoryId) {
return Ember.isEmpty(updateTime) ||
loading ||
(publishToCategory && !topicTimerCategoryId);
},
@computed("topic.visible")
excludeCategoryId(visible) {
if (visible) return this.get('topic.category_id');
},
@on('init')
@observes("topicTimer", "topicTimer.execute_at", "topicTimer.duration")
_setUpdateTime() {
let time = null;
const executeAt = this.get('topicTimer.execute_at');
if (executeAt && this.get("topicTimer.based_on_last_post")) {
time = this.get("topicTimer.duration");
} else if (executeAt) {
const closeTime = moment(executeAt);
if (closeTime > moment()) {
time = closeTime.format("YYYY-MM-DD HH:mm");
}
}
this.set("topicTimer.updateTime", time);
}
});

View File

@ -8,7 +8,10 @@ const TOMORROW = 'tomorrow';
const LATER_THIS_WEEK = 'later_this_week';
const THIS_WEEKEND = 'this_weekend';
const NEXT_WEEK = 'next_week';
const TWO_WEEKS = 'two_weeks';
const NEXT_MONTH = 'next_month';
const FOREVER = 'forever';
export const PICK_DATE_AND_TIME = 'pick_date_and_time';
export const SET_BASED_ON_LAST_POST = 'set_based_on_last_post';
@ -44,14 +47,13 @@ export default Combobox.extend({
});
}
if (day < 5) {
if (day < 5 && this.get('includeWeekend')) {
selections.push({
id: THIS_WEEKEND,
name: I18n.t('topic.auto_update_input.this_weekend')
});
}
if (day !== 7) {
selections.push({
id: NEXT_WEEK,
@ -59,6 +61,11 @@ export default Combobox.extend({
});
}
selections.push({
id: TWO_WEEKS,
name: I18n.t('topic.auto_update_input.two_weeks')
});
if (moment().endOf('month').date() !== now.date()) {
selections.push({
id: NEXT_MONTH,
@ -66,6 +73,13 @@ export default Combobox.extend({
});
}
if (this.get('includeForever')) {
selections.push({
id: FOREVER,
name: I18n.t('topic.auto_update_input.forever')
});
}
selections.push({
id: PICK_DATE_AND_TIME,
name: I18n.t('topic.auto_update_input.pick_date_and_time')
@ -118,7 +132,7 @@ export default Combobox.extend({
if (time) {
if (state.id === LATER_TODAY) {
time = time.format('h a');
} else if (state.id === NEXT_MONTH) {
} else if (state.id === NEXT_MONTH || state.id === TWO_WEEKS) {
time = time.format('MMM D');
} else {
time = time.format('ddd, h a');
@ -133,7 +147,7 @@ export default Combobox.extend({
output += `<span>${state.text}</span>`;
if (time) {
if (time && state.id !== FOREVER) {
output += `<span class='future-date-input-selector-datetime'>${time}</span>`;
}
@ -166,10 +180,18 @@ export default Combobox.extend({
time = time.add(1, 'week').day(1).hour(timeOfDay).minute(0);
icon = 'briefcase';
break;
case TWO_WEEKS:
time = time.add(2, 'week').hour(timeOfDay).minute(0);
icon = 'briefcase';
break;
case NEXT_MONTH:
time = time.add(1, 'month').startOf('month').hour(timeOfDay).minute(0);
icon = 'briefcase';
break;
case FOREVER:
time = time.add(1000, 'year').hour(timeOfDay).minute(0);
icon = 'gavel';
break;
case PICK_DATE_AND_TIME:
time = null;
icon = 'calendar-plus-o';

View File

@ -21,6 +21,7 @@ export default TextField.extend({
groups = [],
currentUser = this.currentUser,
includeMentionableGroups = this.get('includeMentionableGroups') === 'true',
includeMessageableGroups = this.get('includeMessageableGroups') === 'true',
includeGroups = this.get('includeGroups') === 'true',
allowedUsers = this.get('allowedUsers') === 'true';
@ -52,6 +53,7 @@ export default TextField.extend({
includeGroups,
allowedUsers,
includeMentionableGroups,
includeMessageableGroups,
group: self.get("group")
});

View File

@ -1,67 +1,51 @@
import { default as computed, observes } from "ember-addons/ember-computed-decorators";
import { default as computed } from "ember-addons/ember-computed-decorators";
import ModalFunctionality from 'discourse/mixins/modal-functionality';
import TopicTimer from 'discourse/models/topic-timer';
import { popupAjaxError } from 'discourse/lib/ajax-error';
export const CLOSE_STATUS_TYPE = 'close';
const OPEN_STATUS_TYPE = 'open';
export const OPEN_STATUS_TYPE = 'open';
export const PUBLISH_TO_CATEGORY_STATUS_TYPE = 'publish_to_category';
const DELETE_STATUS_TYPE = 'delete';
const REMINDER_TYPE = 'reminder';
export const DELETE_STATUS_TYPE = 'delete';
export const REMINDER_TYPE = 'reminder';
export default Ember.Controller.extend(ModalFunctionality, {
loading: false,
updateTime: null,
topicTimer: Ember.computed.alias("model.topic_timer"),
selection: Ember.computed.alias('model.topic_timer.status_type'),
autoOpen: Ember.computed.equal('selection', OPEN_STATUS_TYPE),
autoClose: Ember.computed.equal('selection', CLOSE_STATUS_TYPE),
autoDelete: Ember.computed.equal('selection', DELETE_STATUS_TYPE),
publishToCategory: Ember.computed.equal('selection', PUBLISH_TO_CATEGORY_STATUS_TYPE),
reminder: Ember.computed.equal('selection', REMINDER_TYPE),
showTimeOnly: Ember.computed.or('autoOpen', 'autoDelete', 'reminder'),
isPublic: "true",
@computed("model.closed")
timerTypes(closed) {
publicTimerTypes(closed) {
return [
{ id: CLOSE_STATUS_TYPE, name: I18n.t(closed ? 'topic.temp_open.title' : 'topic.auto_close.title'), },
{ id: OPEN_STATUS_TYPE, name: I18n.t(closed ? 'topic.auto_reopen.title' : 'topic.temp_close.title') },
{ id: PUBLISH_TO_CATEGORY_STATUS_TYPE, name: I18n.t('topic.publish_to_category.title') },
{ id: DELETE_STATUS_TYPE, name: I18n.t('topic.auto_delete.title') },
{ id: DELETE_STATUS_TYPE, name: I18n.t('topic.auto_delete.title') }
];
},
@computed()
privateTimerTypes() {
return [
{ id: REMINDER_TYPE, name: I18n.t('topic.reminder.title') }
];
},
@computed('updateTime', 'loading', 'publishToCategory', 'topicTimer.category_id')
saveDisabled(updateTime, loading, publishToCategory, topicTimerCategoryId) {
return Ember.isEmpty(updateTime) ||
loading ||
(publishToCategory && !topicTimerCategoryId);
},
@computed("model.visible")
excludeCategoryId(visible) {
if (visible) return this.get('model.category_id');
},
@observes("topicTimer.execute_at", "topicTimer.duration")
_setUpdateTime() {
if (!this.get('topicTimer.execute_at')) return;
let time = null;
if (this.get("topicTimer.based_on_last_post")) {
time = this.get("topicTimer.duration");
} else if (this.get("topicTimer.execute_at")) {
const closeTime = moment(this.get('topicTimer.execute_at'));
if (closeTime > moment()) {
time = closeTime.format("YYYY-MM-DD HH:mm");
}
@computed("isPublic", 'publicTimerTypes', 'privateTimerTypes')
selections(isPublic, publicTimerTypes, privateTimerTypes) {
if (isPublic === 'true') {
return publicTimerTypes;
} else {
return privateTimerTypes;
}
},
this.set("updateTime", time);
@computed('isPublic', 'model.topic_timer', 'model.private_topic_timer')
topicTimer(isPublic, publicTopicTimer, privateTopicTimer) {
if (isPublic === 'true') {
return publicTopicTimer;
} else {
return privateTopicTimer;
}
},
_setTimer(time, statusType) {
@ -85,10 +69,11 @@ export default Ember.Controller.extend(ModalFunctionality, {
this.set('model.closed', result.closed);
} else {
const topicTimer = this.get('isPublic') === 'true' ? 'topic_timer' : 'private_topic_timer';
this.set(`model.${topicTimer}`, Ember.Object.create({}));
this.setProperties({
topicTimer: Ember.Object.create({}),
selection: null,
updateTime: null
});
}
}).catch(error => {
@ -98,11 +83,11 @@ export default Ember.Controller.extend(ModalFunctionality, {
actions: {
saveTimer() {
this._setTimer(this.get("updateTime"), this.get('selection'));
this._setTimer(this.get("topicTimer.updateTime"), this.get('topicTimer.status_type'));
},
removeTimer() {
this._setTimer(null, this.get('selection'));
this._setTimer(null, this.get('topicTimer.status_type'));
}
}
});

View File

@ -48,9 +48,9 @@ export default Ember.Controller.extend({
};
},
@computed("model.mentionable")
displayGroupMessageButton(mentionable) {
return this.currentUser && mentionable;
@computed("model.messageable")
displayGroupMessageButton(messageable) {
return this.currentUser && messageable;
},
@observes('model.user_count')

View File

@ -61,7 +61,7 @@ export default Ember.Controller.extend(PasswordValidation, UsernameValidation, N
username: this.get('accountUsername'),
name: this.get('accountName'),
password: this.get('accountPassword'),
userCustomFields
user_custom_fields: userCustomFields
}
}).then(result => {
if (result.success) {

View File

@ -71,7 +71,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
type: 'POST'
}).then(function (result) {
// Successful login
if (result.error) {
if (result && result.error) {
self.set('loggingIn', false);
if (result.reason === 'not_activated') {
self.send('showNotActivated', {

View File

@ -1,5 +1,7 @@
import { CANCELLED_STATUS } from 'discourse/lib/autocomplete';
import Category from 'discourse/models/category';
import { TAG_HASHTAG_POSTFIX } from 'discourse/lib/tag-hashtags';
import { SEPARATOR } from 'discourse/lib/category-hashtags';
var cache = {};
var cacheTime;
@ -27,7 +29,18 @@ function searchTags(term, categories, limit) {
var returnVal = CANCELLED_STATUS;
oldSearch.then((r) => {
var tags = r.results.map((tag) => { return { text: tag.text, count: tag.count }; });
const categoryNames = cats.map(c => c.model.get('name'));
const tags = r.results.map((tag) => {
const tagName = tag.text;
return {
name: tagName,
text: (categoryNames.includes(tagName) ? `${tagName}${TAG_HASHTAG_POSTFIX}` : tagName),
count: tag.count,
};
});
returnVal = cats.concat(tags);
}).always(() => {
oldSearch = null;
@ -55,7 +68,10 @@ export function search(term, siteSettings) {
const limit = 5;
var categories = Category.search(term, { limit });
var numOfCategories = categories.length;
categories = categories.map((category) => { return { model: category }; });
categories = categories.map((category) => {
return { model: category, text: Category.slugFor(category, SEPARATOR) };
});
if (numOfCategories !== limit && siteSettings.tagging_enabled) {
return searchTags(term, categories, limit - numOfCategories);

View File

@ -19,10 +19,10 @@ function calcHeight() {
// iPhone shrinks header and removes footer controls ( back / forward nav )
// at 39px we are at the largest viewport
const smallViewport = (window.screen.height - window.innerHeight) > 40;
const portrait = window.innerHeight > window.innerWidth;
const smallViewport = ((portrait ? window.screen.height : window.screen.width) - window.innerHeight) > 40;
// portrait
if (window.screen.height > window.screen.width) {
if (portrait) {
// iPhone SE, it is super small so just
// have a bit of crop
@ -39,24 +39,22 @@ function calcHeight() {
if (window.screen.height === 736) {
withoutKeyboard = smallViewport ? 353 : 383;
}
// iPad can use innerHeight cause it renders nothing in the footer
if (window.innerHeight > 920) {
withoutKeyboard -= 45;
}
} else {
// landscape
//
// iPad, we have a bigger keyboard
if (window.innerWidth > window.innerHeight && window.innerHeight > 665) {
if (window.innerHeight > 665) {
withoutKeyboard -= 128;
}
}
// iPad portrait also has a bigger keyboard
return Math.max(withoutKeyboard, min);
}

View File

@ -1,7 +1,5 @@
import { ajax } from 'discourse/lib/ajax';
import { findRawTemplate } from 'discourse/lib/raw-templates';
import { TAG_HASHTAG_POSTFIX } from 'discourse/lib/tag-hashtags';
import { SEPARATOR } from 'discourse/lib/category-hashtags';
import Category from 'discourse/models/category';
import { search as searchCategoryTag } from 'discourse/lib/category-tag-search';
import userSearch from 'discourse/lib/user-search';
@ -148,11 +146,7 @@ export function applySearchAutocomplete($input, siteSettings, appEvents, options
width: '100%',
treatAsTextarea: true,
transformComplete(obj) {
if (obj.model) {
return Category.slugFor(obj.model, SEPARATOR);
} else {
return `${obj.text}${TAG_HASHTAG_POSTFIX}`;
}
return obj.text;
},
dataSource(term) {
return searchCategoryTag(term, siteSettings);

View File

@ -7,7 +7,7 @@ var cache = {},
currentTerm,
oldSearch;
function performSearch(term, topicId, includeGroups, includeMentionableGroups, allowedUsers, group, resultsFn) {
function performSearch(term, topicId, includeGroups, includeMentionableGroups, includeMessageableGroups, allowedUsers, group, resultsFn) {
var cached = cache[term];
if (cached) {
resultsFn(cached);
@ -20,6 +20,7 @@ function performSearch(term, topicId, includeGroups, includeMentionableGroups, a
topic_id: topicId,
include_groups: includeGroups,
include_mentionable_groups: includeMentionableGroups,
include_messageable_groups: includeMessageableGroups,
group: group,
topic_allowed_users: allowedUsers }
});
@ -88,6 +89,7 @@ export default function userSearch(options) {
var term = options.term || "",
includeGroups = options.includeGroups,
includeMentionableGroups = options.includeMentionableGroups,
includeMessageableGroups = options.includeMessageableGroups,
allowedUsers = options.allowedUsers,
topicId = options.topicId,
group = options.group;
@ -120,6 +122,7 @@ export default function userSearch(options) {
topicId,
includeGroups,
includeMentionableGroups,
includeMessageableGroups,
allowedUsers,
group,
function(r) {

View File

@ -29,6 +29,8 @@ export function loadTopicView(topic, args) {
});
}
export const ID_CONSTRAINT = /^\d+$/;
const Topic = RestModel.extend({
message: null,
errorLoading: false,

View File

@ -178,6 +178,11 @@ const User = RestModel.extend({
return suspendedTill && moment(suspendedTill).isAfter();
},
@computed("suspended_till")
suspendedForever(suspendedTill) {
return moment().diff(suspendedTill, 'years') < -500;
},
@computed("suspended_till")
suspendedTillDate(suspendedTill) {
return longDate(suspendedTill);

View File

@ -9,7 +9,8 @@ export default function() {
this.route('fromParams', { path: '/' });
this.route('fromParamsNear', { path: '/:nearPost' });
});
this.route('topicBySlug', { path: '/t/:slug', resetNamespace: true });
this.route('topicBySlugOrId', { path: '/t/:slugOrId', resetNamespace: true });
this.route('topicUnsubscribe', { path: '/t/:slug/:id/unsubscribe' });
this.route('discovery', { path: '/', resetNamespace: true }, function() {

View File

@ -0,0 +1,16 @@
import { default as Topic, ID_CONSTRAINT } from 'discourse/models/topic';
import DiscourseURL from 'discourse/lib/url';
export default Discourse.Route.extend({
model(params) {
if (params.slugOrId.match(ID_CONSTRAINT)) {
return { url: `/t/topic/${params.slugOrId}` };
} else {
return Topic.idForSlug(params.slugOrId);
}
},
afterModel(result) {
DiscourseURL.routeTo(result.url, { replaceURL: true });
}
});

View File

@ -1,12 +0,0 @@
import Topic from 'discourse/models/topic';
import DiscourseURL from 'discourse/lib/url';
export default Discourse.Route.extend({
model: function(params) {
return Topic.idForSlug(params.slug);
},
afterModel: function(result) {
DiscourseURL.routeTo(result.url, { replaceURL: true });
}
});

View File

@ -1,4 +1,5 @@
import DiscourseURL from 'discourse/lib/url';
import { ID_CONSTRAINT } from 'discourse/models/topic';
let isTransitioning = false,
scheduledReplace = null,
@ -53,6 +54,7 @@ const TopicRoute = Discourse.Route.extend({
showTopicStatusUpdate() {
const model = this.modelFor('topic');
model.set('topic_timer', Ember.Object.create(model.get('topic_timer')));
model.set('private_topic_timer', Ember.Object.create(model.get('private_topic_timer')));
showModal('edit-topic-timer', { model });
this.controllerFor('modal').set('modalClass', 'edit-topic-timer-modal');
},
@ -157,6 +159,10 @@ const TopicRoute = Discourse.Route.extend({
},
model(params, transition) {
if (params.slug.match(ID_CONSTRAINT)) {
return DiscourseURL.routeTo(`/t/topic/${params.slug}/${params.id}`, { replaceURL: true });
};
const queryParams = transition.queryParams;
let topic = this.modelFor('topic');

View File

@ -5,7 +5,7 @@
{{#if option.model}}
<a href>{{category-link option.model allowUncategorized="true" link="false"}}</a>
{{else}}
<a href>{{d-icon 'tag'}}{{option.text}} x {{option.count}}</a>
<a href>{{d-icon 'tag'}}{{option.name}} x {{option.count}}</a>
{{/if}}
</li>
{{/each}}

View File

@ -2,7 +2,7 @@
{{user-selector topicId=topicId
onChangeCallback='triggerResize'
id="private-message-users"
includeMentionableGroups='true'
includeMessageableGroups='true'
class="span8"
placeholderKey="composer.users_placeholder"
tabindex="1"

View File

@ -0,0 +1,36 @@
<form>
<div class="control-group">
{{combo-box content=timerTypes value=selection width="50%"}}
</div>
<div>
{{#if showTimeOnly}}
{{future-date-input
input=topicTimer.updateTime
statusType=selection
includeWeekend=true
basedOnLastPost=false}}
{{else if publishToCategory}}
<div class="control-group">
<label>{{i18n 'topic.topic_status_update.publish_to'}}</label>
{{category-select-box
value=topicTimer.category_id
excludeCategoryId=excludeCategoryId}}
</div>
{{future-date-input
input=topicTimer.updateTime
statusType=selection
includeWeekend=true
categoryId=topicTimer.category_id
basedOnLastPost=false}}
{{else if autoClose}}
{{future-date-input
input=topicTimer.updateTime
statusType=selection
includeWeekend=true
basedOnLastPost=topicTimer.based_on_last_post
lastPostedAt=model.last_posted_at}}
{{/if}}
</div>
</form>

View File

@ -8,6 +8,8 @@
statusType=statusType
value=selection
input=input
includeWeekend=includeWeekend
includeForever=includeForever
width="50%"
none="topic.auto_update_input.none"}}
</div>

View File

@ -1,51 +1,35 @@
<form>
{{#d-modal-body title="topic.topic_status_update.title" autoFocus="false"}}
<div class="control-group">
{{combo-box content=timerTypes value=selection width="50%"}}
</div>
{{#d-modal-body title="topic.topic_status_update.title" autoFocus="false"}}
<div class="radios">
<label for="public-topic-timer">
{{radio-button id='public-topic-timer' name="topic-timer" value="true" selection=isPublic}}
<b>{{i18n 'topic.topic_status_update.public_timer_types'}}</b>
</label>
<div>
{{#if showTimeOnly}}
{{future-date-input
input=updateTime
statusType=selection
basedOnLastPost=false}}
{{else if publishToCategory}}
<div class="control-group">
<label>{{i18n 'topic.topic_status_update.publish_to'}}</label>
{{category-select-box
value=topicTimer.category_id
excludeCategoryId=excludeCategoryId}}
</div>
{{future-date-input
input=updateTime
statusType=selection
categoryId=topicTimer.category_id
basedOnLastPost=false}}
{{else if autoClose}}
{{future-date-input
input=updateTime
statusType=selection
basedOnLastPost=topicTimer.based_on_last_post
lastPostedAt=model.last_posted_at}}
{{/if}}
</div>
{{/d-modal-body}}
<div class="modal-footer">
{{d-button class="btn-primary"
disabled=saveDisabled
label="topic.topic_status_update.save"
action="saveTimer"}}
{{d-modal-cancel close=(action "closeModal")}}
{{conditional-loading-spinner size="small" condition=loading}}
{{#if topicTimer.execute_at}}
{{d-button class="pull-right btn-danger"
action="removeTimer"
label='topic.topic_status_update.remove'}}
{{/if}}
<label for="private-topic-timer">
{{radio-button id='private-topic-timer' name="topic-timer" value="false" selection=isPublic}}
<b>{{i18n 'topic.topic_status_update.private_timer_types'}}</b>
</label>
</div>
</form>
{{edit-topic-timer-form
topic=model
topicTimer=topicTimer
timerTypes=selections
updateTime=updateTime
closeModal="closeModal"}}
{{/d-modal-body}}
<div class="modal-footer">
{{d-button class="btn-primary"
disabled=saveDisabled
label="topic.topic_status_update.save"
action="saveTimer"}}
{{conditional-loading-spinner size="small" condition=loading}}
{{#if topicTimer.execute_at}}
{{d-button class="pull-right btn-danger"
action="removeTimer"
label='topic.topic_status_update.remove'}}
{{/if}}
</div>

View File

@ -199,6 +199,13 @@
</div>
{{/if}}
{{#if model.private_topic_timer.execute_at}}
{{topic-timer-info
statusType=model.private_topic_timer.status_type
executeAt=model.private_topic_timer.execute_at
duration=model.private_topic_timer.duration}}
{{/if}}
{{topic-timer-info
statusType=model.topic_timer.status_type
executeAt=model.topic_timer.execute_at

View File

@ -84,7 +84,13 @@
{{#if model.isSuspended}}
<div class='suspended'>
{{d-icon "ban"}}
<b>{{i18n 'user.suspended_notice' date=model.suspendedTillDate}}</b><br>
<b>
{{#if model.suspendedForever}}
{{i18n 'user.suspended_permanently'}}
{{else}}
{{i18n 'user.suspended_notice' date=model.suspendedTillDate}}
{{/if}}
</b><br>
{{#if model.suspend_reason}}
<b>{{i18n 'user.suspended_reason'}}</b> {{model.suspend_reason}}
{{/if}}

View File

@ -33,6 +33,11 @@ createWidget('priority-faq-link', {
export default createWidget('hamburger-menu', {
tagName: 'div.hamburger-panel',
settings: {
showCategories: true,
maxWidth: 300
},
adminLinks() {
const { currentUser } = this;
@ -176,15 +181,22 @@ export default createWidget('hamburger-menu', {
}
results.push(this.attach('menu-links', {name: 'general-links', contents: () => this.generalLinks() }));
results.push(this.listCategories());
results.push(h('hr'));
if (this.settings.showCategories) {
results.push(this.listCategories());
results.push(h('hr'));
}
results.push(this.attach('menu-links', {name: 'footer-links', omitRule: true, contents: () => this.footerLinks(prioritizeFaq, faqUrl) }));
return results;
},
html() {
return this.attach('menu-panel', { contents: () => this.panelContents() });
return this.attach('menu-panel', {
contents: () => this.panelContents(),
maxWidth: this.settings.maxWidth,
});
},
clickOutside() {

View File

@ -4,10 +4,10 @@ import hbs from 'discourse/widgets/hbs-compiler';
createWidget('header-contents', {
tagName: 'div.contents.clearfix',
template: hbs`
{{attach widget="home-logo"}}
{{attach widget="home-logo" attrs=attrs}}
<div class="panel clearfix">{{yield}}</div>
{{#if attrs.topic}}
{{attach widget="header-topic-info"}}
{{attach widget="header-topic-info" attrs=attrs}}
{{/if}}
`,
});

View File

@ -31,8 +31,10 @@ export default createWidget('link', {
},
buildAttributes(attrs) {
return { href: this.href(attrs),
title: attrs.title ? I18n.t(attrs.title) : this.label(attrs) };
return {
href: this.href(attrs),
title: attrs.title ? I18n.t(attrs.title) : this.label(attrs)
};
},
label(attrs) {

View File

@ -10,52 +10,85 @@ createWidget('post-admin-menu-button', jQuery.extend(ButtonClass, {
}
}));
export function buildManageButtons(attrs, currentUser) {
if (!currentUser) {
return [];
}
let contents = [];
if (!attrs.isWhisper && currentUser.staff) {
const buttonAtts = {
action: 'togglePostType',
icon: 'shield',
className: 'toggle-post-type'
};
if (attrs.isModeratorAction) {
buttonAtts.label = 'post.controls.revert_to_regular';
} else {
buttonAtts.label = 'post.controls.convert_to_moderator';
}
contents.push(buttonAtts);
}
if (attrs.canManage) {
contents.push({
icon: 'cog',
label: 'post.controls.rebake',
action: 'rebakePost',
className: 'rebuild-html'
});
if (attrs.hidden) {
contents.push({
icon: 'eye',
label: 'post.controls.unhide',
action: 'unhidePost',
className: 'unhide-post'
});
}
}
if (currentUser.admin) {
contents.push({
icon: 'user',
label: 'post.controls.change_owner',
action: 'changePostOwner',
className: 'change-owner'
});
}
if (attrs.canManage || attrs.canWiki) {
if (attrs.wiki) {
contents.push({
action: 'toggleWiki',
label: 'post.controls.unwiki',
icon: 'pencil-square-o',
className: 'wiki wikied'
});
} else {
contents.push({
action: 'toggleWiki',
label: 'post.controls.wiki',
icon: 'pencil-square-o',
className: 'wiki'
});
}
}
return contents;
}
export default createWidget('post-admin-menu', {
tagName: 'div.post-admin-menu.popup-menu',
html(attrs) {
html() {
const contents = [];
contents.push(h('h3', I18n.t('admin_title')));
if (!attrs.isWhisper && this.currentUser.staff) {
const buttonAtts = { action: 'togglePostType', icon: 'shield', className: 'toggle-post-type' };
if (attrs.isModeratorAction) {
buttonAtts.label = 'post.controls.revert_to_regular';
} else {
buttonAtts.label = 'post.controls.convert_to_moderator';
}
contents.push(this.attach('post-admin-menu-button', buttonAtts));
}
if (attrs.canManage) {
contents.push(this.attach('post-admin-menu-button', {
icon: 'cog', label: 'post.controls.rebake', action: 'rebakePost', className: 'rebuild-html'
}));
if (attrs.hidden) {
contents.push(this.attach('post-admin-menu-button', {
icon: 'eye', label: 'post.controls.unhide', action: 'unhidePost', className: 'unhide-post'
}));
}
}
if (this.currentUser.admin) {
contents.push(this.attach('post-admin-menu-button', {
icon: 'user', label: 'post.controls.change_owner', action: 'changePostOwner', className: 'change-owner'
}));
}
// toggle Wiki button
if (attrs.wiki) {
contents.push(this.attach('post-admin-menu-button', {
action: 'toggleWiki', label: 'post.controls.unwiki', icon: 'pencil-square-o', className: 'wiki wikied'
}));
} else {
contents.push(this.attach('post-admin-menu-button', {
action: 'toggleWiki', label: 'post.controls.wiki', icon: 'pencil-square-o', className: 'wiki'
}));
}
buildManageButtons(this.attrs, this.currentUser).forEach(b => {
contents.push(this.attach('post-admin-menu-button', b));
});
return contents;
},

View File

@ -1,4 +1,4 @@
import { createWidget } from 'discourse/widgets/widget';
import { applyDecorators, createWidget } from 'discourse/widgets/widget';
import { avatarAtts } from 'discourse/widgets/actions-summary';
import { h } from 'virtual-dom';
@ -29,16 +29,29 @@ function registerButton(name, builder) {
_builders[name] = builder;
}
export function buildButton(name, widget) {
let { attrs, state, siteSettings } = widget;
let builder = _builders[name];
if (builder) {
let button = builder(attrs, state, siteSettings);
if (button && !button.id) {
button.id = name;
}
return button;
}
}
registerButton('like', attrs => {
if (!attrs.showLike) { return; }
const className = attrs.liked ? 'toggle-like has-like fade-out' : 'toggle-like like';
const button = {
action: 'like',
icon: 'heart',
icon: attrs.liked ? 'd-liked' : 'd-unliked',
className
};
if (attrs.canToggleLike) {
button.title = attrs.liked ? 'post.controls.undo_like' : 'post.controls.like';
} else if (attrs.liked) {
@ -180,6 +193,7 @@ registerButton('bookmark', attrs => {
}
return {
id: attrs.bookmarked ? 'bookmark' : 'unbookmark',
action: 'toggleBookmark',
title: attrs.bookmarked ? "bookmarks.created" : "bookmarks.not_bookmarked",
className,
@ -197,13 +211,13 @@ registerButton('admin', attrs => {
registerButton('delete', attrs => {
if (attrs.canRecoverTopic) {
return { action: 'recoverPost', title: 'topic.actions.recover', icon: 'undo', className: 'recover' };
return { id: 'recover_topic', action: 'recoverPost', title: 'topic.actions.recover', icon: 'undo', className: 'recover' };
} else if (attrs.canDeleteTopic) {
return { action: 'deletePost', title: 'topic.actions.delete', icon: 'trash-o', className: 'delete' };
return { id: 'delete_topic', action: 'deletePost', title: 'topic.actions.delete', icon: 'trash-o', className: 'delete' };
} else if (attrs.canRecover) {
return { action: 'recoverPost', title: 'post.controls.undelete', icon: 'undo', className: 'recover' };
return { id: 'recover', action: 'recoverPost', title: 'post.controls.undelete', icon: 'undo', className: 'recover' };
} else if (attrs.canDelete) {
return { action: 'deletePost', title: 'post.controls.delete', icon: 'trash-o', className: 'delete' };
return { id: 'delete', action: 'deletePost', title: 'post.controls.delete', icon: 'trash-o', className: 'delete' };
}
});
@ -228,16 +242,18 @@ export default createWidget('post-menu', {
buildKey: attrs => `post-menu-${attrs.id}`,
attachButton(name, attrs) {
const builder = _builders[name];
if (builder) {
const buttonAtts = builder(attrs, this.state, this.siteSettings);
if (buttonAtts) {
return this.attach(this.settings.buttonType, buttonAtts);
}
attachButton(name) {
let buttonAtts = buildButton(name, this);
if (buttonAtts) {
return this.attach(this.settings.buttonType, buttonAtts);
}
},
menuItems() {
let result = this.siteSettings.post_menu.split('|');
return result;
},
html(attrs, state) {
const { siteSettings } = this;
@ -249,7 +265,7 @@ export default createWidget('post-menu', {
const allButtons = [];
let visibleButtons = [];
const orderedButtons = siteSettings.post_menu.split('|');
const orderedButtons = this.menuItems();
// If the post is a wiki, make Edit more prominent
if (attrs.wiki) {
@ -329,7 +345,8 @@ export default createWidget('post-menu', {
postControls.push(repliesButton);
}
postControls.push(h('div.actions', visibleButtons));
let extraControls = applyDecorators(this, 'extra-controls', attrs, state);
postControls.push(h('div.actions', visibleButtons.concat(extraControls)));
if (state.adminVisible) {
postControls.push(this.attach('post-admin-menu', attrs));
}
@ -368,7 +385,7 @@ export default createWidget('post-menu', {
return this.sendWidgetAction('toggleLike');
}
const $heart = $(`[data-post-id=${attrs.id}] .d-icon-heart`);
const $heart = $(`[data-post-id=${attrs.id}] .toggle-like .d-icon`);
$heart.closest('button').addClass('has-like');
if (!Ember.testing) {

View File

@ -20,3 +20,8 @@ export default class RawHtml {
}
RawHtml.prototype.type = 'Widget';
// TODO: Improve how helpers are registered for vdom compliation
if (typeof Discourse !== "undefined") {
Discourse.__widget_helpers.rawHtml = RawHtml;
}

View File

@ -177,7 +177,7 @@ export default createWidget('topic-admin-menu', {
icon: visible ? 'eye-slash' : 'eye',
label: visible ? 'actions.invisible' : 'actions.visible' });
if (this.currentUser.get('staff')) {
if (details.get('can_convert_topic')) {
buttons.push({ className: 'topic-admin-convert',
action: isPrivateMessage ? 'convertToPublicTopic' : 'convertToPrivateMessage',
icon: isPrivateMessage ? 'comment' : 'envelope',

View File

@ -89,6 +89,10 @@ createWidget('user-menu-links', {
export default createWidget('user-menu', {
tagName: 'div.user-menu',
settings: {
maxWidth: 300
},
panelContents() {
const path = this.currentUser.get('path');
@ -104,7 +108,10 @@ export default createWidget('user-menu', {
},
html() {
return this.attach('menu-panel', { contents: () => this.panelContents() });
return this.attach('menu-panel', {
maxWidth: this.settings.maxWidth,
contents: () => this.panelContents()
});
},
clickOutside() {

View File

@ -91,6 +91,8 @@ function drawWidget(builder, attrs, state) {
}
}
this.transformed = this.transform(this.attrs, this.state);
let contents = this.html(attrs, state);
if (this.name) {
const beforeContents = applyDecorators(this, 'before', attrs, state) || [];
@ -173,6 +175,10 @@ export default class Widget {
}
}
transform() {
return {};
}
defaultState() {
return {};
}

View File

@ -194,21 +194,9 @@
.mobile-view {
.flagged-posts {
.flagged-post-details {
flex-wrap: wrap;
justify-content: flex-start;
.flagged-post-avatar {
margin-right: 10px;
}
.flagged-post-excerpt {
width: 70%;
}
.flaggers {
margin-left: 4em;
margin-bottom: 1em;
.flagged-post {
.flag-user-lists {
display: block;
}
}
}

View File

@ -8,8 +8,18 @@
text-align: left;
}
.radios {
margin-bottom: 10px;
}
label {
vertical-align: middle;
display: inline-block;
padding-right: 5px;
input {
vertical-align: middle;
}
}
.btn.pull-right {

View File

@ -4,7 +4,6 @@
.d-header {
left: 0;
z-index: 1000;
padding-top: 3px;
height: 60px;
.d-icon-home {

View File

@ -69,8 +69,8 @@
}
.topic-status-info {
border-top: 1px solid $primary-low;
padding-top: 10px;
border-top: 1px solid $primary-low;
padding: 10px 0px;
height: 20px;
max-width: 757px;
}

View File

@ -47,11 +47,9 @@ class Admin::EmailTemplatesController < Admin::AdminController
error_messages = []
if subject_result[:error_messages].present?
TranslationOverride.upsert!(I18n.locale, "#{key}.subject_template", subject_result[:old_value])
error_messages << format_error_message(subject_result, "subject")
end
if body_result[:error_messages].present?
TranslationOverride.upsert!(I18n.locale, "#{key}.text_body_template", body_result[:old_value])
error_messages << format_error_message(body_result, "body")
end
@ -61,6 +59,9 @@ class Admin::EmailTemplatesController < Admin::AdminController
render_serialized(key, AdminEmailTemplateSerializer, root: 'email_template', rest_serializer: true)
else
TranslationOverride.upsert!(I18n.locale, "#{key}.subject_template", subject_result[:old_value])
TranslationOverride.upsert!(I18n.locale, "#{key}.text_body_template", body_result[:old_value])
render_json_error(error_messages)
end
end

View File

@ -167,6 +167,12 @@ class ApplicationController < ActionController::Base
render_json_error I18n.t(opts[:custom_message] || type), type: type, status: status_code
else
begin
current_user
rescue Discourse::InvalidAccess
return render plain: I18n.t(type), status: status_code
end
render html: build_not_found_page(status_code, opts[:include_ember] ? 'application' : 'no_ember')
end
end

View File

@ -29,7 +29,7 @@ class ExportCsvController < ApplicationController
def export_params
@_export_params ||= begin
params.require(:entity)
params.permit(:entity, args: [:name, :start_date, :end_date, :category_id, :group_id, :trust_level])
params.permit(:entity, args: [:name, :start_date, :end_date, :category_id, :group_id, :trust_level]).to_h
end
end
end

View File

@ -125,15 +125,17 @@ class GroupsController < ApplicationController
order = "#{params[:order]} #{dir} NULLS LAST"
end
total = group.users.count
members = group.users
users = group.users.human_users
total = users.count
members = users
.order('NOT group_users.owner')
.order(order)
.order(username_lower: dir)
.limit(limit)
.offset(offset)
owners = group.users
owners = users
.order(order)
.order(username_lower: dir)
.where('group_users.owner')

View File

@ -31,7 +31,7 @@ class InvitesController < ApplicationController
def perform_accept_invitation
params.require(:id)
params.permit(:username, :name, :password, :user_custom_fields)
params.permit(:username, :name, :password, user_custom_fields: {})
invite = Invite.find_by(invite_key: params[:id])
if invite.present?

View File

@ -331,6 +331,8 @@ class ListController < ApplicationController
def build_topic_list_options
options = {}
params[:page] = params[:page].to_i rescue 1
TopicQuery.public_valid_options.each do |key|
options[key] = params[key]
end

View File

@ -247,7 +247,7 @@ class SessionController < ApplicationController
end
json = { result: "ok" }
unless SiteSetting.forgot_password_strict
unless SiteSetting.hide_email_address_taken
json[:user_found] = user_presence
end

View File

@ -100,8 +100,11 @@ class TagsController < ::ApplicationController
def destroy
guardian.ensure_can_admin_tags!
tag_name = params[:tag_id]
tag = Tag.find_by_name(tag_name)
raise Discourse::NotFound if tag.nil?
TopicCustomField.transaction do
Tag.find_by_name(tag_name).destroy
tag.destroy
StaffActionLogger.new(current_user).log_custom('deleted_tag', subject: tag_name)
end
render json: success_json

View File

@ -372,6 +372,19 @@ class UsersController < ApplicationController
message: activation.message,
user_id: user.id
}
elsif SiteSetting.hide_email_address_taken && user.errors[:primary_email]&.include?(I18n.t('errors.messages.taken'))
session["user_created_message"] = activation.success_message
if existing_user = User.find_by_email(user.primary_email&.email)
Jobs.enqueue(:critical_user_email, type: :account_exists, user_id: existing_user.id)
end
render json: {
success: true,
active: user.active?,
message: activation.success_message,
user_id: user.id
}
else
errors = user.errors.to_hash
errors[:email] = errors.delete(:primary_email) if errors[:primary_email]
@ -698,11 +711,17 @@ class UsersController < ApplicationController
end
end
if params[:include_mentionable_groups] == "true" && current_user
to_render[:groups] = Group.mentionable(current_user)
.where("name ILIKE :term_like", term_like: "#{term}%")
.map do |m|
{ name: m.name, full_name: m.full_name }
if current_user
groups =
if params[:include_mentionable_groups] == 'true'
Group.mentionable(current_user)
elsif params[:include_messageable_groups] == 'true'
Group.messageable(current_user)
end
if groups
to_render[:groups] = groups.where("name ILIKE :term_like", term_like: "#{term}%")
.map { |m| { name: m.name, full_name: m.full_name } }
end
end

View File

@ -1,3 +1,5 @@
require_dependency 'user_destroyer'
module Jobs
class FixPrimaryEmailsForStagedUsers < Jobs::Onceoff
def execute_onceoff(args)

View File

@ -2,6 +2,7 @@ require 'open-uri'
require 'nokogiri'
require 'excon'
require_dependency 'retrieve_title'
require_dependency 'topic_link'
module Jobs
class CrawlTopicLink < Jobs::Base

View File

@ -9,7 +9,7 @@ module Jobs
raise Discourse::InvalidParameters.new(:upload_id) if upload_id.blank?
return unless upload = Upload.find_by(id: upload_id)
return unless user = User.find(args[:user_id] || upload.user_id)
return unless user = User.find_by(id: args[:user_id] || upload.user_id)
Discourse.avatar_sizes.each do |size|
OptimizedImage.create_for(upload, size, size, filename: upload.original_filename, allow_animation: SiteSetting.allow_animated_avatars)

View File

@ -12,7 +12,15 @@ module Jobs
return unless user = User.find_by(id: user_id)
UserAvatar.import_url_for_user(url, user, override_gravatar: args[:override_gravatar])
begin
UserAvatar.import_url_for_user(
'/assets/vorablesen/placeholder-user-ed74bdf68223d030da1b7ddc44f59faf9c5a184388c94aff91632d5bf166a9e5.png',
user,
override_gravatar: args[:override_gravatar]
)
rescue Discourse::InvalidParameters => e
raise e unless e.message == 'url'
end
end
end

View File

@ -8,7 +8,7 @@ module Jobs
end
web_hook = WebHook.find_by(id: args[:web_hook_id])
raise Discourse::InvalidParameters(:web_hook_id) if web_hook.blank?
raise Discourse::InvalidParameters.new(:web_hook_id) if web_hook.blank?
unless ping_event?(args[:event_type])
return unless web_hook.active?

View File

@ -1,3 +1,5 @@
require_dependency 'post'
module Jobs
class NotifyMailingListSubscribers < Jobs::Base

View File

@ -3,9 +3,12 @@ module Jobs
class UpdateTopRedirection < Jobs::Base
def execute(args)
if user = User.find_by(id: args[:user_id])
user.user_option.update_column(:last_redirected_to_top_at, args[:redirected_at])
end
return if args[:user_id].blank? || args[:redirected_at].blank?
UserOption
.where(user_id: args[:user_id])
.limit(1)
.update_all(last_redirected_to_top_at: args[:redirected_at])
end
end

View File

@ -1,3 +1,7 @@
require_dependency 'admin_dashboard_data'
require_dependency 'group'
require_dependency 'group_message'
module Jobs
class DashboardStats < Jobs::Scheduled
every 30.minutes

View File

@ -101,7 +101,9 @@ module Jobs
end
def content
@article_rss_item.content.try(:force_encoding, "UTF-8").try(:scrub) || @article_rss_item.description.try(:force_encoding, "UTF-8").try(:scrub)
@article_rss_item.content_encoded&.force_encoding("UTF-8")&.scrub ||
@article_rss_item.content&.force_encoding("UTF-8")&.scrub ||
@article_rss_item.description&.force_encoding("UTF-8")&.scrub
end
def title

View File

@ -83,6 +83,15 @@ class UserNotifications < ActionMailer::Base
)
end
def account_exists(user, opts = {})
build_email(
user.email,
template: 'user_notifications.account_exists',
locale: user_locale(user),
email: user.email
)
end
def short_date(dt)
if dt.year == Time.now.year
I18n.l(dt, format: :short_no_year)

View File

@ -108,10 +108,6 @@ class Category < ActiveRecord::Base
Category.reset_topic_ids_cache
end
def self.last_updated_at
order('updated_at desc').limit(1).pluck(:updated_at).first.to_i
end
def self.scoped_to_permissions(guardian, permission_types)
if guardian.try(:is_admin?)
all
@ -564,5 +560,5 @@ end
#
# index_categories_on_email_in (email_in) UNIQUE
# index_categories_on_topic_count (topic_count)
# unique_index_categories_on_name (name) UNIQUE
# unique_index_categories_on_name ((COALESCE(parent_category_id, '-1'::integer)), name) UNIQUE
#

View File

@ -9,7 +9,7 @@ class ColorScheme < ActiveRecord::Base
"tertiary" => '0f82af',
"quaternary" => 'c14924',
"header_background" => '111111',
"header_primary" => '333333',
"header_primary" => 'dddddd',
"highlight" => 'a87137',
"danger" => 'e45735',
"success" => '1ca551',

View File

@ -118,13 +118,6 @@ class GlobalSetting
c[:db] = redis_db if redis_db != 0
c[:db] = 1 if Rails.env == "test"
if redis_sentinels.present?
c[:sentinels] = redis_sentinels.split(",").map do |address|
host, port = address.split(":")
{ host: host, port: port }
end.to_a
end
c.freeze
end
end

View File

@ -307,6 +307,7 @@ class Group < ActiveRecord::Base
def self.ensure_consistency!
reset_all_counters!
refresh_automatic_groups!
refresh_has_messages!
end
def self.reset_all_counters!
@ -330,6 +331,18 @@ class Group < ActiveRecord::Base
args.each { |group| refresh_automatic_group!(group) }
end
def self.refresh_has_messages!
exec_sql <<-SQL
UPDATE groups g SET has_messages = false
WHERE NOT EXISTS (SELECT tg.id
FROM topic_allowed_groups tg
INNER JOIN topics t ON t.id = tg.topic_id
WHERE tg.group_id = g.id
AND t.deleted_at IS NULL)
AND g.has_messages = true
SQL
end
def self.ensure_automatic_groups!
AUTO_GROUPS.each_key do |name|
refresh_automatic_group!(name) unless lookup_group(name)

View File

@ -91,6 +91,16 @@ class Post < ActiveRecord::Base
q.order('posts.created_at ASC')
}
scope :raw_match, -> (pattern, type = 'string') {
type = type&.downcase
case type
when 'string'
where('raw ILIKE ?', "%#{pattern}%")
when 'regex'
where('raw ~ ?', pattern)
end
}
delegate :username, to: :user

View File

@ -15,6 +15,6 @@ end
#
# Indexes
#
# index_post_custom_fields_on_name_and_value (name)
# index_post_custom_fields_on_name_and_value (name, "left"(value, 200))
# index_post_custom_fields_on_post_id_and_name (post_id,name)
#

View File

@ -411,6 +411,7 @@ class Topic < ActiveRecord::Base
def reload(options = nil)
@post_numbers = nil
@public_topic_timer = nil
@private_topic_timer = nil
super(options)
end
@ -1002,6 +1003,10 @@ SQL
@public_topic_timer ||= topic_timers.find_by(deleted_at: nil, public_type: true)
end
def private_topic_timer(user)
@private_topic_Timer ||= topic_timers.find_by(deleted_at: nil, public_type: false, user_id: user.id)
end
def delete_topic_timer(status_type, by_user: Discourse.system_user)
options = { status_type: status_type }
options.merge!(user: by_user) unless TopicTimer.public_types[status_type]
@ -1022,8 +1027,9 @@ SQL
def set_or_create_timer(status_type, time, by_user: nil, timezone_offset: 0, based_on_last_post: false, category_id: SiteSetting.uncategorized_category_id)
return delete_topic_timer(status_type, by_user: by_user) if time.blank?
topic_timer_options = { topic: self }
topic_timer_options.merge!(user: by_user) unless TopicTimer.public_types[status_type]
public_topic_timer = !!TopicTimer.public_types[status_type]
topic_timer_options = { topic: self, public_type: public_topic_timer }
topic_timer_options.merge!(user: by_user) unless public_topic_timer
topic_timer = TopicTimer.find_or_initialize_by(topic_timer_options)
topic_timer.status_type = status_type
@ -1330,6 +1336,7 @@ end
# index_topics_on_bumped_at (bumped_at)
# index_topics_on_created_at_and_visible (created_at,visible)
# index_topics_on_id_and_deleted_at (id,deleted_at)
# index_topics_on_lower_title (lower((title)::text))
# index_topics_on_pinned_at (pinned_at)
# index_topics_on_pinned_globally (pinned_globally)
#

View File

@ -38,26 +38,19 @@ class TopicUser < ActiveRecord::Base
end
def auto_notification(user_id, topic_id, reason, notification_level)
if TopicUser.where("user_id = :user_id AND topic_id = :topic_id AND (notifications_reason_id IS NULL OR
(notification_level < :notification_level AND notification_level > :normal_notification_level))",
user_id: user_id, topic_id: topic_id, notification_level: notification_level,
normal_notification_level: notification_levels[:regular]).exists?
change(user_id, topic_id,
notification_level: notification_level,
notifications_reason_id: reason
)
end
should_change = TopicUser
.where(user_id: user_id, topic_id: topic_id)
.where("notifications_reason_id IS NULL OR (notification_level < :min AND notification_level > :max)", min: notification_level, max: notification_levels[:regular])
.exists?
change(user_id, topic_id, notification_level: notification_level, notifications_reason_id: reason) if should_change
end
def auto_notification_for_staging(user_id, topic_id, reason)
topic_user = TopicUser.find_or_initialize_by(user_id: user_id, topic_id: topic_id)
topic_user.notification_level = notification_levels[:watching]
topic_user.notifications_reason_id = reason
topic_user.save
def auto_notification_for_staging(user_id, topic_id, reason, notification_level = notification_levels[:watching])
change(user_id, topic_id, notification_level: notification_level, notifications_reason_id: reason)
end
def unwatch_categories!(user, category_ids)
track_threshold = user.user_option.auto_track_topics_after_msecs
sql = <<SQL

View File

@ -170,6 +170,7 @@ end
#
# Indexes
#
# index_uploads_on_extension (lower((extension)::text))
# index_uploads_on_id_and_url (id,url)
# index_uploads_on_sha1 (sha1) UNIQUE
# index_uploads_on_url (url)

View File

@ -1124,6 +1124,7 @@ end
# name :string
# seen_notification_id :integer default(0), not null
# last_posted_at :datetime
# email :string(513)
# password_hash :string(64)
# salt :string(32)
# active :boolean default(FALSE), not null
@ -1157,6 +1158,7 @@ end
#
# idx_users_admin (id)
# idx_users_moderator (id)
# index_users_on_email (lower((email)::text)) UNIQUE
# index_users_on_last_posted_at (last_posted_at)
# index_users_on_last_seen_at (last_seen_at)
# index_users_on_uploaded_avatar_id (uploaded_avatar_id)

View File

@ -42,6 +42,7 @@ end
#
# Indexes
#
# index_user_emails_on_email (lower((email)::text)) UNIQUE
# index_user_emails_on_user_id (user_id)
# index_user_emails_on_user_id_and_primary (user_id,primary) UNIQUE
#

View File

@ -77,7 +77,7 @@ class UserOption < ActiveRecord::Base
$redis.expire(key, delay)
# delay the update
Jobs.enqueue_in(delay / 2, :update_top_redirection, user_id: self.id, redirected_at: Time.zone.now)
Jobs.enqueue_in(delay / 2, :update_top_redirection, user_id: self.user_id, redirected_at: Time.zone.now)
end
def should_be_redirected_to_top
@ -92,10 +92,10 @@ class UserOption < ActiveRecord::Base
return if user.trust_level > 0 && user.last_seen_at && user.last_seen_at > 1.month.ago
# top must be in the top_menu
return unless SiteSetting.top_menu =~ /(^|\|)top(\||$)/i
return unless SiteSetting.top_menu[/\btop\b/i]
# not enough topics
return unless period = SiteSetting.min_redirected_to_top_period(1.days.ago)
return unless period = SiteSetting.min_redirected_to_top_period(1.day.ago)
if !user.seen_before? || (user.trust_level == 0 && !redirected_to_top_yet?)
update_last_redirected_to_top!

View File

@ -1,5 +1,5 @@
class GroupShowSerializer < BasicGroupSerializer
attributes :is_group_user, :is_group_owner, :mentionable
attributes :is_group_user, :is_group_owner, :mentionable, :messageable
def include_is_group_user?
authenticated?
@ -21,6 +21,10 @@ class GroupShowSerializer < BasicGroupSerializer
authenticated?
end
def include_messageable?
authenticated?
end
def mentionable
Group.mentionable(scope.user).exists?(id: object.id)
end

View File

@ -61,6 +61,7 @@ class TopicViewSerializer < ApplicationSerializer
:message_archived,
:tags,
:topic_timer,
:private_topic_timer,
:unicode_title,
:message_bus_last_id,
:participant_count
@ -118,6 +119,7 @@ class TopicViewSerializer < ApplicationSerializer
result[:can_create_post] = true if scope.can_create?(Post, object.topic)
result[:can_reply_as_new_topic] = true if scope.can_reply_as_new_topic?(object.topic)
result[:can_flag_topic] = actions_summary.any? { |a| a[:can_act] }
result[:can_convert_topic] = true if scope.can_convert_topic?(object.topic)
result
end
@ -241,6 +243,15 @@ class TopicViewSerializer < ApplicationSerializer
TopicTimerSerializer.new(object.topic.public_topic_timer, root: false)
end
def include_private_topic_timer?
scope.user
end
def private_topic_timer
timer = object.topic.private_topic_timer(scope.user)
TopicTimerSerializer.new(timer, root: false)
end
def tags
object.topic.tags.map(&:name)
end

View File

@ -93,7 +93,7 @@ class PostAlerter
DiscourseEvent.trigger(:before_create_notifications_for_users, users, post)
users.each do |user|
notification_level = TopicUser.get(post.topic, user).try(:notification_level)
if notified.include?(user) || notification_level == TopicUser.notification_levels[:watching]
if notified.include?(user) || notification_level == TopicUser.notification_levels[:watching] || user.staged?
create_notification(user, Notification.types[:private_message], post)
end
end

View File

@ -16,6 +16,10 @@ class UserActivator
@message = activator.activate
end
def success_message
activator.success_message
end
private
def activator
@ -38,6 +42,10 @@ end
class ApprovalActivator < UserActivator
def activate
success_message
end
def success_message
I18n.t("login.wait_approval")
end
end
@ -52,6 +60,11 @@ class EmailActivator < UserActivator
user_id: user.id,
email_token: email_token.token
)
success_message
end
def success_message
I18n.t("login.activate_email", email: Rack::Utils.escape_html(user.email))
end
end
@ -62,6 +75,10 @@ class LoginActivator < UserActivator
def activate
log_on_user(user)
user.enqueue_welcome_message('welcome_user')
success_message
end
def success_message
I18n.t("login.active")
end
end

View File

@ -104,6 +104,6 @@
<% content_for :title do %><%= @title %><% end %>
<% elsif @category %>
<% content_for :title do %><%= @category.name %> - <%= SiteSetting.title %><% end %>
<% elsif params[:page] %>
<% elsif params[:page].to_i > 1 %>
<% content_for :title do %><%=t 'page_num', num: params[:page].to_i + 1 %> - <%= SiteSetting.title %><% end %>
<% end %>

View File

@ -2029,25 +2029,25 @@ ar:
like: "أعجبهم هذا"
vote: "صوت لهذا"
by_you:
off_topic: "لقد ابلغت ان المنشور خارج الموضوع"
spam: "لقد ابلغت ان المنشور سبام"
inappropriate: "لقد ابلغت ان المنشور غير لائق"
notify_moderators: "لقد ابلغت المشرفين"
off_topic: "لقد ابلغت ان هذا المنشور خارج الموضوع"
spam: "لقد ابلغت ان هذا المنشور سبام"
inappropriate: "لقد ابلغت ان هذا المنشور غير لائق"
notify_moderators: "لقد ابلغت المشرفين عن هذا المنشور"
notify_user: "لقد أرسلت رسالة إلى هذا العضو"
bookmark: "لقد علّمت هذا المنشور"
bookmark: "لقد وضعت علامة مرجعية علي هذا المنشور"
like: "أعجبت بهذا المنشور"
vote: "لقد صوّت على هذا المنشور"
by_you_and_others:
off_topic:
zero: "أنت أبلّغت بأن هذا المنشور خارج الموضوع."
one: "أنت وآخر أبلّغتما بأن هذا المنشور خارج الموضوع."
one: "أنت وشخص اخر أبلّغتما بأن هذا المنشور خارج الموضوع."
two: "أنت و {{count}} آخرون أبلغتم بأن هذا المنشور خارج الموضوع"
few: "أنت و {{count}} آخرون أبلغتم بأن هذا المنشور خارج الموضوع"
many: "أنت و {{count}} آخرون أبلغتم بأن هذا المنشور خارج الموضوع"
other: "أنت و {{count}} آخرون أبلغتم بأن هذا المنشور خارج الموضوع"
spam:
zero: "أنت أبلّغت بأن هذا هذا المنشور سبام."
one: "أنت وآخر أبلّغتما بأن هذا المنشور سبام."
one: "أنت وشخص آخر أبلّغتما بأن هذا المنشور سبام."
two: "أنت و {{count}} آخرون أبلّغتم بأن هذا المنشور سبام."
few: "أنت و {{count}} آخرون أبلّغتم بأن هذا المنشور سبام."
many: "أنت و {{count}} آخرون أبلّغتم بأن هذا المنشور سبام."
@ -2060,12 +2060,12 @@ ar:
many: "أنت و {{count}} آخرون أبلّغتم بأن هذا المنشور غير لائق."
other: "أنت و {{count}} آخرون أبلّغتم بأن هذا المنشور غير لائق."
notify_moderators:
zero: "أنت أبلّغت المشرفين."
one: "أنت و شخص آخر أبلّغتما المشرفين."
two: "أنت و {{count}} آخرون أبلّغتم المشرفين."
few: "أنت و {{count}} آخرون أبلّغتم المشرفين."
many: "أنت و {{count}} آخرون أبلّغتم المشرفين."
other: "أنت و {{count}} آخرون أبلّغتم المشرفين."
zero: "أنت أبلّغت المشرفين عن هذا المنشور."
one: "أنت و شخص آخر أبلّغتما المشرفين عن هذا المنشور."
two: "أنت و {{count}} آخرون أبلّغتم المشرفين عن هذا المنشور."
few: "أنت و {{count}} آخرون أبلّغتم المشرفين عن هذا المنشور."
many: "أنت و {{count}} آخرون أبلّغتم المشرفين عن هذا المنشور."
other: "أنت و {{count}} آخرون أبلّغتم المشرفين عن هذا المنشور."
notify_user:
zero: "أنت أرسلت رسالة لهذا العضو."
one: "أنت و شخص اخر ارسلتما رسالة لهذا العضو."
@ -2074,91 +2074,99 @@ ar:
many: "أنت و {{count}} آخرون ارسلتم رسالة لهذا العضو."
other: "أنت و {{count}} آخرون ارسلتم رسالة لهذا العضو."
bookmark:
zero: "أنت عَلَّمتَ هذه المشاركة."
one: "أنت و شخص آخر عَلَّمتُما هذه المشاركة."
two: "أنت و {{count}} آخران عَلَّمتُم هذه المشاركة."
few: "أنت و {{count}} آخرون عَلَّمتُم هذه المشاركة."
many: "أنت و {{count}} آخرون عَلَّمتُم هذه المشاركة."
other: "أنت و {{count}} آخرون عَلَّمتُم هذه المشاركة."
zero: "أنت وضعت علامة مرجعية علي هذا المنشور"
one: "أنت و شخص آخر وضعتما علامة مرجعية علي هذا المنشور"
two: "أنت و {{count}} آخرون وضعتم علامة مرجعية علي هذا المنشور"
few: "أنت و {{count}} آخرون وضعتم علامة مرجعية علي هذا المنشور"
many: "أنت و {{count}} آخرون وضعتم علامة مرجعية علي هذا المنشور"
other: "أنت و {{count}} آخرون وضعتم علامة مرجعية علي هذا المنشور"
like:
zero: عجبك هذا"
one: عجب هذا شخصا واحدا غيرك"
two: عجب هذا شخصين غيرك"
few: عجب هذا {{count}} أشخاص غيرك"
many: عجب هذا {{count}} شخصا غيرك"
other: عجب هذا {{count}} شخص غيرك"
zero: نت اعجبت بهذا المنشور"
one: نت و شخص آخر اعجبتما بهذا المنشور"
two: نت و {{count}} آخرون اعجبتم بهذا المنشور"
few: نت و {{count}} آخرون اعجبتم بهذا المنشور"
many: نت و {{count}} آخرون اعجبتم بهذا المنشور"
other: نت و {{count}} آخرون اعجبتم بهذا المنشور"
vote:
zero: "أنت و {{count}} أشخاص أخرين صوتو لهذا الموضوع"
one: "أنت و {{count}} أشخاص أخرين صوتو لهذا الموضوع"
two: "أنت و {{count}} أشخاص أخرين صوتو لهذا الموضوع"
few: "أنت و {{count}} أشخاص أخرين صوتو لهذا الموضوع"
many: "أنت و {{count}} أشخاص أخرين صوتو لهذا الموضوع"
other: "أنت و {{count}} أشخاص أخرين صوتو لهذا الموضوع"
zero: "أنت صوت علي هذا المنشور"
one: "أنت و شخص آخر صوتما علي هذا المنشور"
two: "أنت و {{count}} آخرون صوتم علي هذا المنشور"
few: "أنت و {{count}} آخرون صوتم علي هذا المنشور"
many: "أنت و {{count}} آخرون صوتم علي هذا المنشور"
other: "أنت و {{count}} آخرون صوتم علي هذا المنشور"
by_others:
off_topic:
zero: "لم يتم الاشارة لهذا كخارج عن الموضوع."
one: "شخص أشار لهذا كخارج عن الموضوع."
two: "شخصان أشارا لهذا كخارج عن الموضوع."
few: "{{count}} أشخاص أشاروا لهذا كخارج عن الموضوع."
many: "{{count}} شخص أشار لهذا كخارج عن الموضوع."
other: "{{count}} شخص أشار لهذا كخارج عن الموضوع."
zero: "لم يبلغ احد بأن هذا المنشور خارج الموضوع"
one: "عضو واحد أبلغ بأن هذا المنشور خارج الموضوع"
two: "{{count}} عضو أبلغ بأن هذا المنشور خارج الموضوع"
few: "{{count}} عضو أبلغ بأن هذا المنشور خارج الموضوع"
many: "{{count}} عضو أبلغ بأن هذا المنشور خارج الموضوع"
other: "{{count}} عضو أبلغ بأن هذا المنشور خارج الموضوع"
spam:
zero: "لم يتم الاشارة لهذا كغير مفيد,"
one: "شخص أشار لهذا كغير مفيد."
two: "شخصان أشارا لهذا كغير مفيد."
few: "{{count}} أشخاص أشاروا لهذا كغير مفيد."
many: "{{count}} شخص أشار لهذا كغير مفيد."
other: "{{count}} شخص أشار لهذا كغير مفيد."
zero: "لم يبلّغ احد بأن هذا المنشور سبام."
one: "عضو واحد أبلّغ بأن هذا المنشور سبام."
two: "{{count}} عضو أبلّغ بأن هذا المنشور سبام."
few: "{{count}} عضو أبلّغ بأن هذا المنشور سبام."
many: "{{count}} عضو أبلّغ بأن هذا المنشور سبام."
other: "{{count}} عضو أبلّغ بأن هذا المنشور سبام."
inappropriate:
zero: "لم تتم الإشارة لهذا كغير ملائم."
one: "شخص أشار لهذا كغير ملائم."
two: "شخصان أشارا لهذا كغير ملائم."
few: "{{count}} أشخاص أشاروا لهذا كغير ملائم."
many: "{{count}} شخص أشاروا لهذا كغير ملائم."
other: "{{count}} شخص أشاروا لهذا كغير ملائم."
zero: "لم يبلغ احد بأن هذا المنشور غير لائق."
one: "عضو واحد أبلّغ بأن هذا المنشور غير لائق."
two: "{{count}} عضو أبلّغ بأن هذا المنشور غير لائق."
few: "{{count}} عضو أبلّغ بأن هذا المنشور غير لائق."
many: "{{count}} عضو أبلّغ بأن هذا المنشور غير لائق."
other: "{{count}} عضو أبلّغ بأن هذا المنشور غير لائق."
notify_moderators:
zero: "1 عضو علّم هذا للمراقبين"
one: "1 عضو علّم هذا للمراقبين"
two: "{{count}} أعضاء علّمو هذا للمراقبين"
few: "{{count}} أعضاء علّمو هذا للمراقبين"
many: "{{count}} أعضاء علّمو هذا للمراقبين"
other: "{{count}} أعضاء علّمو هذا للمراقبين"
zero: "لم يبلغ احد المشرفين عن هذا المنشور"
one: "عضو واحد أبلّغ المشرفين عن هذا المنشور"
two: "{{count}} عضو أبلّغ المشرفين عن هذا المنشور"
few: "{{count}} عضو أبلّغ المشرفين عن هذا المنشور"
many: "{{count}} عضو أبلّغ المشرفين عن هذا المنشور"
other: "{{count}} عضو أبلّغ المشرفين عن هذا المنشور"
notify_user:
zero: "لم يُرسل شيء لهذا المستخدم"
one: "أرسل شخص واحد رسالة لهذا المستخدم"
two: "أرسل شخصين رسالة لهذا المستخدم"
few: "أرسل {{count}} أشخاص رسالة لهذا المستخدم"
many: "أرسل {{count}} شخصا رسالة لهذا المستخدم"
other: "أرسل {{count}} شخص رسالة لهذا المستخدم"
zero: "لم يرسل احد رسالة لهذا العضو"
one: "عضو واحد ارسل رسالة لهذا العضو"
two: "{{count}} عضو ارسل رسالة لهذا العضو"
few: "{{count}} عضو ارسل رسالة لهذا العضو"
many: "{{count}} عضو ارسل رسالة لهذا العضو"
other: "{{count}} عضو ارسل رسالة لهذا العضو"
bookmark:
zero: "لم يعلّم أحد هذه المشاركة"
one: "شخص واحد علّم هذه المشاركة"
two: "شخصان علّما هذه المشاركة"
few: "{{count}} أشخاص علّموا هذه المشاركة"
many: "{{count}} شخصًا علّموا هذه المشاركة"
other: "{{count}} شخص علّموا هذه المشاركة"
zero: "لم يضع احد علامة مرجعية علي هذا المنشور"
one: "عضو واحد وضع علامة مرجعية علي هذا المنشور"
two: "{{count}} عضو وضع علامة مرجعية علي هذا المنشور"
few: "{{count}} عضو وضع علامة مرجعية علي هذا المنشور"
many: "{{count}} عضو وضع علامة مرجعية علي هذا المنشور"
other: "{{count}} عضو وضع علامة مرجعية علي هذا المنشور"
like:
zero: "لم يعجب هذا أحدا"
one: "أعجب هذا شخص واحد"
two: "أعجب هذا شخصان"
few: "أعجب هذا {{count}} أشخاص"
many: "أعجب هذا {{count}} شخصا"
other: "أعجب هذا {{count}} شخص"
zero: "لم يعجب احد بهذا المنشور"
one: "عضو واحد اعجب بهذا المنشور"
two: "{{count}} عضو اعجب بهذا المنشور"
few: "{{count}} عضو اعجب بهذا المنشور"
many: "{{count}} عضو اعجب بهذا المنشور"
other: "{{count}} عضو اعجب بهذا المنشور"
vote:
zero: "لم يصوّت أحد على هذه المشاركة"
one: "صوّت شخص واحد على هذه المشاركة"
two: "صوّت شخصان على هذه المشاركة"
few: "صوّت {{count}} أشخاص على هذه المشاركة"
many: "صوّت {{count}} شخصا على هذه المشاركة"
other: "صوّت {{count}} شخص على هذه المشاركة"
zero: "لم يصوت احد علي هذا المنشور"
one: "عضو واحد صوت علي هذا المنشور"
two: "{{count}} عضو صوت علي هذا المنشور"
few: "{{count}} عضو صوت علي هذا المنشور"
many: "{{count}} عضو صوت علي هذا المنشور"
other: "{{count}} عضو صوت علي هذا المنشور"
delete:
confirm:
zero: "لا شيء لحذفه."
one: "أمتأكد من حذف المشاركة؟"
two: "أمتأكد من حذف المشاركتين؟"
few: "أمتأكد من حذف المشاركات هذه؟"
many: "أمتأكد من حذف المشاركات هذه؟"
other: "أمتأكد من حذف المشاركات هذه؟"
one: "هل انت متاكد انك تريد حذف هذا المنشور؟"
two: "هل انت متاكد انك تريد حذف كل هذة المنشورات؟"
few: "هل انت متاكد انك تريد حذف كل هذة المنشورات؟"
many: "هل انت متاكد انك تريد حذف كل هذة المنشورات؟"
other: "هل انت متاكد انك تريد حذف كل هذة المنشورات؟"
merge:
confirm:
zero: "لا يوجد منشورات لدمجها"
one: "هل انت متاكد انك تريد دمج هذا المنشور؟"
two: "هل انت متاكد انك تريد دمج هذان المنشوران؟"
few: "هل انت متاكد انك تريد دمج الـ {{count}} منشور؟"
many: "هل انت متاكد انك تريد دمج الـ {{count}} منشور؟"
other: "هل انت متاكد انك تريد دمج الـ {{count}} منشور؟"
revisions:
controls:
first: "أول مراجعة"
@ -2168,19 +2176,32 @@ ar:
hide: "أخفِ المراجعة"
show: "أظهر المراجعة"
revert: "ارجع إلى هذه المراجعة"
edit_wiki: "حرّر الويكي"
edit_wiki: "عدل الwiki"
edit_post: "عدل المنشور"
comparing_previous_to_current_out_of_total: "<strong>{{previous}}</strong> <i class='fa fa-arrows-h'></i> <strong>{{current}}</strong> / {{total}}"
displays:
inline:
button: 'HTML'
title: "اعرض النسخة المنسقة في عمود واحد مع تمييز الاسطر المضافة و المحذوفة"
button: 'عمود واحد'
side_by_side:
title: "أظهر فروقات الخرج المصيّر جنبًا إلى جنب"
button: 'HTML'
title: "اعرض الفروقات في النسخة المنسقة جنبا إلي جنب"
button: 'عمودين'
side_by_side_markdown:
title: "أظهر فروقات المصدر الخامّ جنبًا إلى جنب"
title: "اعرض الفروقات في النسخة الخام جنبا إلي جنب"
button: 'عمودين خام'
raw_email:
displays:
raw:
title: "اعرض نص الرساله الخام"
button: 'خام'
text_part:
title: "اظهر الجزء النصي من رسالة البريد الالكتروني"
button: 'نص'
html_part:
title: "اظهر جزء الـ HTML من رسالة البريد الالكتروني"
button: 'HTML'
category:
can: 'يمكنها&hellip;'
can: 'قادر علي&hellip;'
none: '(غير مصنف)'
all: 'كل الأقسام'
choose: 'اختر قسم &hellip;'
@ -2193,7 +2214,7 @@ ar:
tags: "الوسوم"
tags_allowed_tags: "اسمح فقط لهذة الوسمة بالاستخدام في هذا القسم."
tags_allowed_tag_groups: "اسمح فقط للأوسمة من هذة المجموعات بالاستخدام في هذا القسم."
tags_placeholder: "(اختياري) قائمة العلامات الوصفية المسموح بها"
tags_placeholder: "(اختياري) قائمة الاوسمة المسموح بها"
tag_groups_placeholder: "(اختياريّ) قائمة مجموعات الوسوم المسموح بها"
topic_featured_link_allowed: "اسمح بالروابط المُميزة بهذا القسم."
delete: 'احذف القسم'
@ -2201,7 +2222,7 @@ ar:
create_long: 'أنشئ قسم جديد'
save: 'احفظ القسم'
slug: 'عنوان القسم في الURL'
slug_placeholder: '(اختياريّ) كلمات مفصولة بشَرطة للعنوان'
slug_placeholder: '(اختياريّ) كلمات مفصولة-بشرطة للعنوان'
creation_error: حدثت مشكلة أثناء إنشاء القسم.
save_error: حدث خطأ في حفظ القسم.
name: "اسم القسم"
@ -2213,7 +2234,7 @@ ar:
background_color: "لون الخلفية"
foreground_color: "لون المقدمة"
name_placeholder: "كلمة أو كلمتين على الأكثر"
color_placeholder: "أيّ لون وبّ"
color_placeholder: "أيّ لون متوافق مع الانترنت"
delete_confirm: "هل تريد فعلاً حذف هذا القسم؟"
delete_error: "حدث خطأ في حذف القسم."
list: "عرض الأقسام"
@ -2224,7 +2245,7 @@ ar:
special_warning: "تحذير: هذا القسم هو قسم اصلي إعدادات الحماية له لا يمكن تعديلها. إذا لم تكن تريد استخدام هذا القسم، قم بحذفة بدلا من تطويعة لأغراض اخري."
images: "الصور"
email_in: "تعيين بريد إلكتروني خاص:"
email_in_allow_strangers: "قبول بريد إلكتروني من مستخدمين لا يملكون حسابات"
email_in_allow_strangers: "قبول بريد إلكتروني من زوار لا يملكون حسابات"
email_in_disabled: "عُطّل إرسال المشاركات عبر البريد الإلكترونيّ من إعدادات الموقع. لتفعيل نشر المشاركات الجديدة عبر البريد،"
email_in_disabled_click: 'قم بتفعيل خيار "email in" في الإعدادات'
suppress_from_homepage: "امنع هذا القسم من الظهور في الصفحة الرئيسية."
@ -2235,8 +2256,9 @@ ar:
subcategory_list_style: "أسلوب عرض قائمة الأقسام الفرعية:"
sort_order: "رتب قائمة الموضوعات حسب:"
default_view: "قائمة الموضوعات الإفتراضية"
default_top_period: "فترة الاكثر مشاهدة الافتراضية"
allow_badges_label: "السماح بالحصول على الأوسمة في هذا القسم"
edit_permissions: "حرّر التّصاريح"
edit_permissions: "عدل التصاريح"
add_permission: "أضف تصريحًا"
this_year: "هذه السنة"
position: "المكان"
@ -2262,53 +2284,72 @@ ar:
description: "لن يتم إشعارك بأي موضوعات جديدة في هذه الأقسام ولن يتم عرضها في قائمة الموضوعات المنشورة مؤخراً."
sort_options:
default: "افترضى"
likes: "اعجاب"
op_likes: "الاعجابات الاساسية للمنشور"
likes: "الاعجابات"
op_likes: "الاعجابات علي المنشور الاساسي"
views: "المشاهدات"
posts: "المنشورات"
activity: "النشاط"
posters: "البوستر"
category: "قسم"
created: "انشئ "
sort_ascending: نازلى'
posters: "الإعلانات"
category: "القسم"
created: "تاريخ الإنشاء"
sort_ascending: صاعدي'
sort_descending: 'تنازلي'
subcategory_list_styles:
rows: "صفوف"
rows_with_featured_topics: "صفوف مع الموضوعات المميزة"
boxes: "مربعات"
boxes_with_featured_topics: "مربعات مع الموضوعات المميزة"
flagging:
title: 'شكرا لمساعدتك في إبقاء مجتمعنا نظيفاً.'
action: 'التبليغ عن مشاركة'
take_action: "أجراء العمليه "
title: 'شكرا لمساعدتك في إبقاء مجتمعنا متحضرا.'
action: 'ابلغ عن المنشور'
take_action: "اتخذ اجراء"
notify_action: 'رسالة'
official_warning: 'تحذير رسمي'
delete_spammer: "احذف ناشر السخام"
delete_spammer: "احذف ناشر السبام"
delete_confirm_MF: "{posts, plural,\n zero {ليس للمستخدم أيّة مشاركات}\n other {}\n}\n{topics, plural,\n zero {\n {posts, plural,\n zero {أو مواضيع.}\n other {ليس للمستخدم أيّة مواضيع.}\n }\n }\n other {{posts, plural, zero{.} other{}}}\n}\nأنت على وشك\n{posts, plural,\n zero {{topics, plural, zero {} other {حذف}}}\n other {حذف}\n}\n{posts, plural,\n zero {}\n one {مشاركة واحدة}\n two {مشاركتين}\n few {# مشاركات}\n many {# مشاركة}\n other {# مشاركة}\n}\n{posts, plural, zero {} other {{topics, plural, zero {} other {و}}}}\n{topics, plural,\n zero {}\n one {موضوع واحد}\n two {موضوعين}\n few {# مواضيع}\n many {# موضوعًا}\n other {# موضوع}\n}\n{posts, plural,\n zero {{topics, plural, zero {} other {له، و}}}\n other {{topics, plural, zero {له، و} other {للمستخدم، و}}}\n}\nإزالة حسابه، ومنع التّسجيل من عنوان IP هذا <b>{ip_address}</b>، وإضافة عنوان البريد الإلكترونيّ <b>{email}</b> إلى قائمة منع دائم. أمتأكّد حقًّا من أنّ هذا المستخدم ناشر سخام؟"
yes_delete_spammer: "نعم، احذف ناشر السخام"
yes_delete_spammer: "نعم، احذف ناشر السبام"
ip_address_missing: "(N/A)"
hidden_email_address: "(مخفي)"
submit_tooltip: "إرسال تبليغ"
take_action_tooltip: "الوصول إلى الحد الأعلى للتبليغات دون انتظار تبليغات أكثر من أعضاء الموقع."
cant: "المعذرة، لا يمكنك التبليغ عن هذه المشاركة في هذه اللحظة."
notify_staff: 'أعلِم الطّاقم بسريّة'
submit_tooltip: "إرسال البلاغ"
take_action_tooltip: "الوصول إلى الحد الأعلى للبلاغات دون انتظار بلاغات أكثر من أعضاء الموقع."
cant: "عذرا، لا يمكنك الابلاغ عن هذا المنشور في هذه اللحظة."
notify_staff: 'ابلغ طاقم العمل بسرية'
formatted_name:
off_topic: "خارج عن الموضوع"
inappropriate: "غير لائق"
spam: "هذا سبام"
custom_placeholder_notify_user: "كن محدد, استدلالي ودائما حسن الاخلاق"
custom_placeholder_notify_moderators: "ممكن تزودنا بمعلومات أكثر عن سبب عدم ارتياحك حول هذه المشاركة؟ زودنا ببعض الروابط و الأمثلة قدر الإمكان."
custom_placeholder_notify_user: "كن محدد و كن بناء و دائما كن حسن الخلق"
custom_placeholder_notify_moderators: "يمكنك تزودنا بمعلومات أكثر عن سبب عدم ارتياحك إلي هذا المنشور؟ زودنا ببعض الروابط و الأمثلة قدر الإمكان."
custom_message:
at_least:
zero: "لا تُدخل أيّ محرف"
one: "أدخل محرفًا واحدًا على الأقلّ"
two: "أدخل محرفين على الأقلّ"
few: "أدخل {{count}} محارف على الأقلّ"
many: "أدخل {{count}} محرفًا على الأقلّ"
other: "أدخل {{count}} محرف على الأقلّ"
one: "أدخل حرف واحد على الأقل"
two: "أدخل {{count}} احرف على الأقل"
few: "أدخل {{count}} احرف على الأقل"
many: "أدخل {{count}} احرف على الأقل"
other: "أدخل {{count}} احرف على الأقل"
more:
zero: "{{count}} حرف متبقي علي الحد الادني..."
one: "حرف واحد متبقي علي الحد الادني..."
two: "{{count}} حرف متبقي علي الحد الادني..."
few: "{{count}} حرف متبقي علي الحد الادني..."
many: "{{count}} حرف متبقي علي الحد الادني..."
other: "{{count}} حرف متبقي علي الحد الادني..."
left:
zero: "{{count}} حرف متبقي علي الحد الاقصي..."
one: "حرف واحد متبقي علي الحد الاقصي..."
two: "{{count}} حرف متبقي علي الحد الاقصي..."
few: "{{count}} حرف متبقي علي الحد الاقصي..."
many: "{{count}} حرف متبقي علي الحد الاقصي..."
other: "{{count}} حرف متبقي علي الحد الاقصي..."
flagging_topic:
title: "شكرا لمساعدتنا في ابقاء مجتمعنا نضيفا"
title: "شكرا لمساعدتنا في ابقاء المجمتع متحضر"
action: "التبليغ عن الموضوع"
notify_action: "رسالة"
topic_map:
title: "ملخص الموضوع"
participants_title: "المشاركون المعتادون"
links_title: "روابط شائعة"
participants_title: "الناشرون المترددون"
links_title: "روابط مشهورة"
links_shown: "أظهر روابط أخرى..."
clicks:
zero: "لا نقرات"
@ -2330,16 +2371,16 @@ ar:
warning:
help: "هذا تحذير رسمي."
bookmarked:
help: "لقد علّمت هذا الموضوع"
help: "لقد وضعت علامة مرجعية علي هذا الموضوع"
locked:
help: "هذا الموضوع مغلق ولم يعد يستقبل ردودا"
help: "هذا الموضوع مغلق, لذا فهو لم يعد يستقبل ردودا"
archived:
help: "هذا الموضوع مؤرشف، لذا فهو مجمّد ولا يمكن تعديله"
help: "هذا الموضوع مؤرشف، لذا فهو مجمد ولا يمكن تعديله"
locked_and_archived:
help: "هذا الموضوع مغلق ومؤرشف، لذا لم يعد يستقبل ردودًا ولا يمكن تغييره"
help: "هذا الموضوع مغلق ومؤرشف، لذا فهو لم يعد يستقبل ردودًا ولا يمكن تغييره"
unpinned:
title: "غير مثبّت"
help: "هذا الموضوع غير مثبّت لك، وسيُعرض بالترتيب العاديّ"
help: "هذا الموضوع غير مثبّت لك، وسيُعرض بالترتيب العادي"
pinned_globally:
title: "مثبّت للعموم"
help: "هذا الموضوع مثبت بشكل عام, سوف يظهر في مقدمة قائمة اخر الموضوعات وفي القسم الخاصة به."
@ -2347,16 +2388,16 @@ ar:
title: "مثبّت"
help: "هذا الموضوع مثبّت لك، وسيُعرض أعلى قسمة"
invisible:
help: "هذا الموضوع غير مصنف لن يظهر في قائمة التصانيف ولايمكن الدخول عليه الابرابط مباشر."
posts: شاركات"
posts_long: "هناك {{number}} مشاركات في هذا الموضوع"
help: "هذا الموضوع غير مدرج, لن يظهر في قائمة الموضوعات ولا يمكن الوصول إلية إلا برابط مباشر"
posts: نشورات"
posts_long: "هناك {{number}} منشور في هذا الموضوع"
posts_likes_MF: |
{count, plural, zero {ليس في هذا الموضوع أي رد} one {في هذا الموضوع رد واحد} two {في هذا الموضوع ردان} few {في هذا الموضوع # ردود} many {في هذا الموضوع # ردا} other {في هذا الموضوع # رد}} {ratio, select,
low {ونسبة الإعجاب إلى المشاركة عالية}
med {ونسبة الإعجاب إلى المشاركة عالية جدا}
high {ونسبة الإعجاب إلى المشاركة مهولة}
other {}}
original_post: "المشاركة الاصلية"
original_post: "المنشور الاصلي"
views: "المشاهدات"
views_lowercase:
zero: "المشاهدات"
@ -2366,6 +2407,13 @@ ar:
many: "المشاهدات"
other: "المشاهدات"
replies: "الردود"
views_long:
zero: "تم مشاهدة هذا الموضوع {{number}} مرة"
one: "تم مشاهدة هذا الموضوع مرة واحدة"
two: "تم مشاهدة هذا الموضوع {{number}} مرة"
few: "تم مشاهدة هذا الموضوع {{number}} مرة"
many: "تم مشاهدة هذا الموضوع {{number}} مرة"
other: "تم مشاهدة هذا الموضوع {{number}} مرة"
activity: "النشاط"
likes: "اعجابات"
likes_lowercase:
@ -2388,10 +2436,11 @@ ar:
history: "تاريخ"
changed_by: "الكاتب {{author}}"
raw_email:
title: "البريد الإلكتروني الوارد"
not_available: "غير متوفر!"
categories_list: "قائمة الأقسام"
filters:
with_topics: "المواضيع %{filter}"
with_topics: "الموضوعات %{filter}"
with_category: "الموضوعات%{filter} في %{category}"
latest:
title: "الأخيرة"
@ -2402,16 +2451,16 @@ ar:
few: "الأخيرة ({{count}})"
many: "الأخيرة ({{count}})"
other: "الأخيرة ({{count}})"
help: "المواضيع التي فيها مشاركات حديثة"
help: "الموضوعات التي بها منشورات حديثة"
hot:
title: "نَشط"
help: "مختارات من مواضيع ساخنة"
help: "مختارات من انشط الموضوعات"
read:
title: "المقروءة"
help: "المواضيع التي قرأتها بترتيب آخر قراءة لها"
help: "المواضيع التي قرأتها بترتيب قرائتك لها"
search:
title: "بحث"
help: "بحث في كل المواضيع"
help: "بحث في كل الموضوعات"
categories:
title: "الأقسام"
title_in: "قسم - {{categoryName}}"
@ -2425,7 +2474,7 @@ ar:
few: "غير المقروءة ({{count}})"
many: "غير المقروءة ({{count}})"
other: "غير المقروءة ({{count}})"
help: "المواضيع التي تتابعها (أو تراقبها) والتي فيها مشاركات غير مقروءة"
help: "الموضوعات التي تتابعها (أو تراقبها) والتي فيها منشورات غير مقروءة"
lower_title_with_count:
zero: "1 غير مقررء "
one: "1 غير مقروء"
@ -2442,7 +2491,7 @@ ar:
many: "{{count}} جديد"
other: "{{count}} جديد"
lower_title: "جديد"
title: "الجديدة"
title: "جديد"
title_with_count:
zero: "الجديدة ({{count}})"
one: "الجديدة ({{count}})"
@ -2452,11 +2501,11 @@ ar:
other: "الجديدة ({{count}})"
help: "المواضيع المنشأة في الأيّام القليلة الماضية"
posted:
title: شاركاتي"
help: "مواضيع شاركت بها "
title: نشوراتي"
help: "مواضيع نشرت بها "
bookmarks:
title: "العلامات"
help: "مواضيع قمت بتفضيلها"
title: "العلامات المرجعية"
help: "موضوعات وضعت عليها علامة مرجعية"
category:
title: "{{categoryName}}"
title_with_count:
@ -2466,30 +2515,30 @@ ar:
few: "{{categoryName}} ({{count}})"
many: "{{categoryName}} ({{count}})"
other: "{{categoryName}} ({{count}})"
help: "آخر الموضوعات في القسم {{categoryName}}"
help: "آخر الموضوعات في قسم {{categoryName}}"
top:
title: "الأكثر مُشاهدة"
help: "أكثر المواضيع نشاطًا في آخر عام، أو شهر أو أسبوع أو يوم"
help: "أكثر المواضيع نشاطًا في آخر عام أو شهر أو أسبوع أو يوم"
all:
title: "كلّها"
title: "كل الوقت"
yearly:
title: "السّنويّة"
title: "سنة"
quarterly:
title: "الرّبعيّة"
title: "ربع سنة"
monthly:
title: "الشّهريّة"
title: "شهر"
weekly:
title: "الأسبوعيّة"
title: "اسبوع"
daily:
title: "اليوميّة"
all_time: "على مرّ الزّمن"
title: "يوم"
all_time: "كل الوقت"
this_year: "سنة"
this_quarter: "ربع"
this_month: "شهر"
this_week: "أسبوع"
today: "يوم"
other_periods: "مشاهدة الأفضل"
browser_update: 'للأسف، <a href="http://www.discourse.org/faq/#browser">متصفّحك قديم جدًّا ليعمل عليه هذا الموقع</a>. من فضلك <a href="http://browsehappy.com">رقّه</a>.'
other_periods: "اعرض الاكثر مشاهدة"
browser_update: 'للأسف، <a href="http://www.discourse.org/faq/#browser">متصفّحك قديم جدًّا ليعمل عليه هذا الموقع</a>. من فضلك <a href="http://browsehappy.com">حدث المتصفح خاصتك</a>.'
permission_types:
full: "انشاء / رد / مشاهدة"
create_post: "رد / مشاهدة"
@ -2499,19 +2548,19 @@ ar:
keyboard_shortcuts_help:
title: 'اختصارات لوحة المفاتيح'
jump_to:
title: 'الانتقال'
title: 'الانتقال إلي'
home: '<b>g</b>، <b>h</b> الرّئيسيّة'
latest: '<b>g</b>، <b>l</b> الأخيرة'
new: '<b>g</b>، <b>n</b> الجديد'
new: '<b>g</b>، <b>n</b> الجديدة'
unread: '<b>g</b>، <b>u</b> غير المقروء'
categories: '<b>g</b>، <b>c</b> الأقسام'
top: '<b>g</b>, <b>t</b> الأعلى'
bookmarks: '<b>g</b>، <b>b</b> العلامات'
profile: '<b>g</b>، <b>p</b> اللاحة'
top: '<b>g</b>, <b>t</b> الاكثر مشاهدة'
bookmarks: '<b>g</b>، <b>b</b> العلامات المرجعية'
profile: '<b>g</b>، <b>p</b> الملف الشخصي'
messages: '<b>g</b>، <b>m</b> الرّسائل'
navigation:
title: 'التنقّل'
jump: '<b>#</b> الانتقال الى المشاركة #'
jump: '<b>#</b> الانتقال الى المنشور#'
back: '<b>u</b> العودة'
up_down: '<b>k</b>/<b>j</b> نقل المحدد &uarr; &darr;'
open: '<b>o</b> أو <b>Enter</b> فتح الموضوع المحدد'
@ -2522,26 +2571,27 @@ ar:
notifications: '<b>n</b> فتح الإشعارات'
hamburger_menu: '<b>=</b> فتح القائمة الرّئيسيّة'
user_profile_menu: '<b>p</b>فتح قائمة المستخدم'
show_incoming_updated_topics: '<b>.</b> عرض المواضيع المحدثة'
show_incoming_updated_topics: '<b>.</b> عرض الموضوعات المحدثة'
search: '<b>/</b> او <b>ctrl</b>+<b>shift</b>+<b>s</b> بحث'
help: '<b>?</b> فتح مساعدة لوحة المفاتيح'
dismiss_new_posts: 'تجاهل جديد / المشاركات <b>x</b>, <b>r</b>'
dismiss_topics: '<b>x</b>, <b>t</b> تجاهل المواضيع'
log_out: '<b>shift</b>+<b>z</b> <b>shift</b>+<b>z</b> الخروج'
dismiss_new_posts: '<b>x</b>, <b>r</b> تجاهل المنشورات الجديدة'
dismiss_topics: '<b>x</b>, <b>t</b> تجاهل الموضوعات'
log_out: '<b>shift</b>+<b>z</b> <b>shift</b>+<b>z</b> تسجيل خروج'
actions:
title: 'إجراءات'
bookmark_topic: '<b>f</b> تبديل علامة مرجعية الموضوع'
pin_unpin_topic: '<b>shift</b>+<b>p</b> تثبيت الموضوع أو إلغاء تثبيته'
bookmark_topic: '<b>f</b> وضع/ازالة علامة مرجعية علي الموضوع'
pin_unpin_topic: '<b>shift</b>+<b>p</b> تثبيت/إلغاء تثبيت الموضوع'
share_topic: '<b>shift</b>+<b>s</b> مشاركة الموضوع'
share_post: '<b>s</b> مشاركة المشاركة'
reply_as_new_topic: 'الرد في موضوع مرتبط <b>t</b>'
share_post: '<b>s</b> مشاركة المنشور'
reply_as_new_topic: '<b>t</b> الرد كموضوع مرتبط'
reply_topic: '<b>shift</b>+<b>r</b> الرد على الموضوع'
reply_post: '<b>r</b> الرد على المشاركة'
quote_post: '<b>q</b> اقتباس المشاركة'
like: '<b>l</b> الإعجاب بالمشاركة'
flag: '<b>!</b> علم على المشاركة'
bookmark: '<b>b</b> أضف مرجعية للمشاركة'
edit: '<b>e</b> تعديل المشاركة'
delete: '<b>d</b> حذف المشاركة'
reply_post: '<b>r</b> الرد على المنشور'
quote_post: '<b>q</b> اقتباس المنشور'
like: '<b>l</b> الإعجاب بالمنشور'
flag: '<b>!</b> الإبلاغ عن المنشور'
bookmark: '<b>b</b> وضع علامة مرجعية علي المنشور'
edit: '<b>e</b> تعديل المنشور'
delete: '<b>d</b> حذف المنشور'
mark_muted: '<b>m</b>، <b>m</b> كتم الموضوع'
mark_regular: '<b>m</b>, <b>r</b> موضوع منظم (الإفتراضي)'
mark_tracking: '<b>m</b>، <b>t</b> متابعة الموضوع'
@ -2618,7 +2668,7 @@ ar:
sort_by_count: "العدد"
sort_by_name: "الاسم"
manage_groups: "أدر مجموعات الوسوم"
manage_groups_description: "اصنع مجموعات لتنظيم الوسوم"
manage_groups_description: "انشئ مجموعات لتنظيم الوسوم"
filters:
without_category: "مواضيع %{tag} %{filter}"
with_category: "موضوعات %{filter}%{tag} في %{category}"
@ -2658,27 +2708,27 @@ ar:
unread: "ليست هناك مواضيع غير مقروءة."
new: "ليست هناك مواضيع جديدة."
read: "لم تقرأ أيّ موضوع بعد."
posted: "لم تشارك في أيّ موضوع بعد."
latest: يست هناك مواضيع حديثة."
hot: "لا يوجد المزيد من المواضيع النشطة"
bookmarks: ا مواضيع معلّمة بعد."
top: "لا يوجد المزيد من المواضيع العليا"
search: "لا نتائج للبحث."
posted: "لم تنشر في أيّ موضوع بعد.."
latest: ا يوجد موضوعات حديثة."
hot: "لا يوجد موضوعات نشطة."
bookmarks: م تقم بوضع علامات مرجعية علي اي موضوع بعد."
top: "لا يوجد موضوعات الاكثر مشاهدة."
search: "لا يوجد نتائج للبحث."
bottom:
latest: يست هناك مواضيع حديثة أخرى."
hot: "لا يوجد المزيد من المواضيع النشطة"
posted: "لا يوجد مواضيع أخرى."
read: "لا مواضيع مقروءة أخرى."
new: "لا مواضيع جديدة أخرى."
unread: "لا مواضيع غير مقروءة أخرى."
top: قد اطلعت على كل المواضيع المميزة حتى هذه اللحظة."
bookmarks: "لايوجد المزيد من المواضيع في المفضلة"
latest: ا يوجد المزيد من الموضوعات الحديثة."
hot: "لا يوجد المزيد من الموضوعات النشطة."
posted: "لا يوجد المزيد من الموضوعات المنشورة."
read: "لا يوجد المزيد من الموضوعات المقروءة."
new: "لا يوجد المزيد من الموضوعات الجديدة."
unread: "لا يوجد المزيد من الموضوعات غير مقروءة."
top: ا يوجد المزيد من الموضوعات الاكثر مشاهدة."
bookmarks: "لا يوجد المزيد من الموضوعات التي عليها علامة مرجعية."
search: "لا نتائج بحث أخرى."
invite:
custom_message: "اجعل دعوتك شخصيّة أكثر بكتابة"
custom_message_link: "رسالة مخصصة"
custom_message_placeholder: "ادخل رسالتك المخصصة"
custom_message_template_forum: "مرحبا. عليك الانضمام إلى هذا المنتدى!"
custom_message_template_forum: "مرحبا. عليك الانضمام إلى هذا المجتمع!"
custom_message_template_topic: "مرحبا. أظن أن هذا الموضوع سيسعدك!"
safe_mode:
enabled: "الوضع الآمن مفعّل، لتخرج منه أغلق نافذة المتصفّح هذه"
@ -2686,18 +2736,18 @@ ar:
type_to_filter: "اكتب للتّرشيح..."
admin:
title: 'مدير المجتمع'
moderator: راقب'
moderator: شرف'
dashboard:
title: "لوحة التحكم"
last_updated: "أخر تحديث للوحة التحكم:"
version: "الإصدارة"
up_to_date: "لديك أحدث إصدارة!"
critical_available: "يتوفّر تحديث لمشاكل حرجة."
version: "الإصدار"
up_to_date: "لديك أحدث إصدار!"
critical_available: "يتوفّر تحديث لمشكلات حرجة."
updates_available: "التحديثات متوفرة."
please_upgrade: "من فضلك رقّ البرمجية!"
no_check_performed: "لم يجرِ التماس التّحديثات. تحقّق من عمل sidekiq."
stale_data: "لم يجرِ التماس التّحديثات حديثًا. تحقّق من عمل sidekiq."
version_check_pending: "يبدو أنك رقّيت الموقع مؤخرا. مذهل!"
no_check_performed: "لم يتم التحقق من التحديثات. تأكد أن sidekiq قيد التشغيل."
stale_data: "لم يتم التحقق من التحديثات مؤخراً. تاكد أن sidekiq قيد التشغيل."
version_check_pending: "يبدو أنك قمت بتحديث الموقع مؤخرا. رائع!"
installed_version: "المثبتة"
latest_version: "الأخيرة"
problems_found: "عُثر على مشاكل في تثبيت نسخة دسكورس هذه:"
@ -2706,12 +2756,12 @@ ar:
no_problems: "لا مشاكل."
moderators: 'المشرفون:'
admins: 'المدراء:'
blocked: 'محظور:'
suspended: 'موقوف:'
blocked: 'محظورون:'
suspended: 'موقوفون:'
private_messages_short: "الرسائل"
private_messages_title: "الرسائل"
mobile_title: "متنقل"
space_free: "{{size}} حرّ"
space_free: "{{size}} فارغ"
uploads: "عمليات الرفع"
backups: "النسخ الاحتياطية"
traffic_short: "المرور"
@ -2729,38 +2779,38 @@ ar:
30_days_ago: "منذ ٣٠ يوم"
all: "الكل"
view_table: "جدول"
view_graph: "شكل رسومي"
view_graph: "رسم بياني"
refresh_report: "تحديث التقرير "
start_date: "تاريخ البدء"
end_date: "تاريخ الإنتهاء"
groups: "جميع الفئات"
groups: "كل المجموعات"
commits:
latest_changes: "آخر تغيير: يرجى التحديث"
by: "بواسطة"
flags:
title: "التبليغات"
active_posts: "المشاركات المبلغ عنها "
old_posts: "المشاركات القديمة المبلغ عنها "
topics: "المواضيع المبلغ عنها "
title: "البلاغات"
active_posts: "المنشورات المبلغ عنها "
old_posts: "المنشورات القديمة المبلغ عنها "
topics: "الموشوعات المبلغ عنها "
agree: "أوافق"
agree_title: "أكد هذا البلاغ لكونه صحيح وصالح"
agree_flag_modal_title: "أوافق مع ..."
agree_flag_hide_post: "اوافق (اخفاء المشاركة + ارسال ر.خ)"
agree_flag_hide_post_title: "أخفي هذه المشاركة وَ تلقائيا بإرسال رسالة للمستخدم وحثهم على تحريرها"
agree_flag_restore_post: "موافق (استعادة المشاركة)"
agree_flag_restore_post_title: "استعد هذه المشاركة."
agree_flag: "الموافقه على التبليغ"
agree_flag_title: "الموافقة مع التَعَلّيم وحفظ المشاركة دون تغيير."
agree_title: "أكد هذا البلاغ كونه صحيح وصالح"
agree_flag_modal_title: "أوافق و ..."
agree_flag_hide_post: "اوافق (اخفاء المنشور + ارسال رسالة خاصة)"
agree_flag_hide_post_title: "أخفي هذا المنشور و ارسل رسالة للعضو تلقائيا تحثه علي تعديلة"
agree_flag_restore_post: "موافق (اعد المنشور)"
agree_flag_restore_post_title: "اعد هذا المنشور."
agree_flag: "الموافقه على البلاغ"
agree_flag_title: "الموافقة علي البلاغ و حفظ المنشور دون تغيير."
defer_flag: "تأجيل"
defer_flag_title: "إزالة البلاغ، لا يتطلب منك إجراء في الوقت الحالي."
delete: "حذف"
delete_title: "حذف المشاركة المرتبطة بهذا البلاغ"
delete_post_defer_flag: "حذف المشاركة مع تأجيل البلاغ"
delete_post_defer_flag_title: "حذف المشاركة. اذا كانت المشاركة الاولى, احذف الموضوع"
delete_post_agree_flag: "حذف المشاركة مع الموافقة على البلاغ"
delete_post_agree_flag_title: "حذف المشاركة. اذا كانت المشاركة الاولى, احذف الموضوع"
delete_flag_modal_title: "حذف مع ..."
delete_spammer: "احذف ناشر السخام"
defer_flag_title: "ازل هذا البلاغ، لا يتطلب منك إجراء في الوقت الحالي."
delete: "احذف"
delete_title: "احذف المنشور المرتبط بهذا البلاغ"
delete_post_defer_flag: "احذف المنشور مع تأجيل البلاغ"
delete_post_defer_flag_title: "احذف المنشور. اذا كان المنشور الاول, احذف الموضوع"
delete_post_agree_flag: "احذف المنشور مع الموافقة على البلاغ"
delete_post_agree_flag_title: "احذف المنشور. اذا كان المنشور الاول, احذف الموضوع"
delete_flag_modal_title: "احذف و..."
delete_spammer: "احذف ناشر السبام"
delete_spammer_title: "احذف المستخدم مع مشاركاته ومواضيعه."
disagree_flag_unhide_post: "أختلف مع البلاغ، إعادة إظهار المشاركة."
disagree_flag_unhide_post_title: "حذف أي بلاغ يخص هذه المشاركة مع إظهارها مرة أخرى"
@ -3061,11 +3111,17 @@ ar:
text: "بعد الـ Header"
footer:
text: "تذييل "
title: "ادخل نص الـ HTML ليتم عرضه في ذيل الصفحة (الفوتر)"
embedded_scss:
text: "CSS مضمن"
head_tag:
text: "</head>"
body_tag:
text: "</body>"
colors:
select_base:
title: "اختر مخطط الالوان الاساسي"
description: "مخطط اساسي"
title: "الألوان"
edit: "عدل مخططات الألوان"
long_title: "مخططات الألوان"
@ -3283,11 +3339,16 @@ ar:
censor: 'راقب (ضلل)'
require_approval: 'يحتاج لموافقة'
flag: 'علم'
action_descriptions:
require_approval: 'المنشورات التي تحتوي على هذه الكلمات تحتاج الى موافقة الطاقم قبل ان يتم رؤيتهم.'
flag: 'اسمح للمنشورات التي تحتوي على هذه الكلمات, ولكن علمهم كـ غير مناسب لكي يتمكن المشرف من مراجعتهم.'
form:
label: 'كلمة جديدة:'
placeholder_regexp: "تعبير اعتيادي"
add: 'اضف'
success: 'نجاح'
upload: "حمل"
upload_successful: "تم الرفع بنجاح. تم اضافة الكلمات"
impersonate:
title: "انتحال الشخصية"
help: "استخدم هذه الأداة لانتحال شخصية حساب مستخدم لأغراض التصحيح. سيتم تسجيل خروجك عندما تنتهي."
@ -3361,10 +3422,15 @@ ar:
suspend_failed: "حدث خطب ما أثناء إيقاف هذا المستخدم {{error}}"
unsuspend_failed: "حدث خطب ما أثناء إلغاء إيقاف هذا المستخدم {{error}}"
suspend_duration: "ما المدّة التي سيُوقف هذا المستخدم خلالها؟"
suspend_duration_units: "(أيام)"
suspend_reason_label: "لماذا هل أنت عالق؟ هذا النص <b>سيكون ظاهراً للكل</b> على صفحة تعريف هذا العضو, وسيكون ظاهراً للعضو عندما يحاول تسجل الدخول. احفظها قصيرة."
suspend_reason_hidden_label: "لماذا انت موقوف؟ هذا النص سيظهر للعضو حين يحاول الولوج. اجعله قصيراً."
suspend_reason: "سبب"
suspend_reason_placeholder: "سبب التوقيف"
suspend_message: "رسالة بريد الكتروني"
suspend_message_placeholder: "اختياري. وفر المزيد من المعلومات حول التوقيف و سيتم ارساله عبر البريد الالكتروني الى العضو."
suspended_by: "محظور من قبل"
suspended_until: "(حتى %{until})"
cant_suspend: "لا يمكن ايقاف هذا العضو"
delete_all_posts: "احذف كل مشاركاته"
delete_all_posts_confirm_MF: "أنت على وشك {POSTS, plural, zero {عدم حذف شيء} one {حذف مشاركة واحدة} two {حذف مشاركتين} few {حذف # مشاركات} many {حذف # مشاركة} other {حذف # مشاركة}}{TOPICS, plural, zero {} one { وموضوع واحد} two { وموضوعين} few { و# مواضيع} many {و# موضوعا} other {و# موضوع}}. أمتأكد؟"
suspend: "علّق"
@ -3385,6 +3451,7 @@ ar:
logged_out: "أخرجنا العضو من كلّ أجهزته"
revoke_admin: 'سحب الإدارة'
grant_admin: 'منحة إدارية'
grant_admin_confirm: "لقد ارسلنا بريداً الكترونياً لتأكيد المدير الجديد. رجاء افتح الرسالة و اتبع التعلميات."
revoke_moderation: 'سحب المراقبة'
grant_moderation: 'منحة مراقبة'
unblock: 'إلغاء حظر'

View File

@ -540,6 +540,7 @@ el:
admin_tooltip: "Αυτός ο χρήστης είναι διαχειριστής"
blocked_tooltip: "Ο χρήστης είναι μπλοκαρισμένος"
suspended_notice: "Αυτός ο χρήστης είναι σε αποβολή μέχρι τις {{date}}."
suspended_permanently: "Ο χρήστης είναι αποβλημένος."
suspended_reason: "Αιτιολογία:"
github_profile: "Github"
email_activity_summary: "Περίληψη Ενεργειών"
@ -1415,7 +1416,9 @@ el:
later_this_week: "Αργότερα αυτή την εβδομάδα"
this_weekend: "Αυτό το Σαββατοκύριακο"
next_week: "Την άλλη εβδομάδα"
two_weeks: "Δύο Εβδομάδες"
next_month: "Τον άλλο μήνα"
forever: "Για Πάντα"
pick_date_and_time: "Επίλεξε ημερομηνία και ώρα"
set_based_on_last_post: "Κλείσε ανάλογα με την τελευταία ανάρτηση"
publish_to_category:

View File

@ -604,6 +604,7 @@ en:
admin_tooltip: "This user is an admin"
blocked_tooltip: "This user is blocked"
suspended_notice: "This user is suspended until {{date}}."
suspended_permanently: "This user is suspended."
suspended_reason: "Reason: "
github_profile: "Github"
email_activity_summary: "Activity Summary"
@ -1554,12 +1555,14 @@ en:
deleted: "The topic has been deleted"
topic_status_update:
title: "Set Topic Timer"
title: "Topic Timer"
save: "Set Timer"
num_of_hours: "Number of hours:"
remove: "Remove Timer"
publish_to: "Publish To:"
when: "When:"
public_timer_types: Topic Timers
private_timer_types: User Topic Timers
auto_update_input:
none: ""
later_today: "Later today"
@ -1567,7 +1570,9 @@ en:
later_this_week: "Later this week"
this_weekend: "This weekend"
next_week: "Next week"
two_weeks: "Two Weeks"
next_month: "Next month"
forever: "Forever"
pick_date_and_time: "Pick date and time"
set_based_on_last_post: "Close based on last post"
publish_to_category:

View File

@ -540,6 +540,7 @@ fi:
admin_tooltip: "Tämä käyttäjä on ylläpitäjä"
blocked_tooltip: "Tämä käyttäjä on estetty"
suspended_notice: "Tämä käyttäjätili on hyllytetty {{date}} asti."
suspended_permanently: "Käyttäjä on hyllytetty."
suspended_reason: "Syy:"
github_profile: "GitHub"
email_activity_summary: "Kooste tapahtumista"
@ -1416,7 +1417,9 @@ fi:
later_this_week: "Myöhemmin tällä viikolla"
this_weekend: "Viikonloppuna"
next_week: "Ensi viikolla"
two_weeks: "Kahden viikon kuluttua"
next_month: "Ensi kuussa"
forever: "Ikuisesti"
pick_date_and_time: "Valitse päivämäärä ja kellonaika"
set_based_on_last_post: "Sulje viimeisimmän viestin mukaan"
publish_to_category:
@ -2959,6 +2962,7 @@ fi:
form:
label: 'Uusi sana:'
placeholder: 'kokonainen sana tai * jokerimerkkinä'
placeholder_regexp: "säännöllinen lauseke"
add: 'Lisä'
success: 'Onnistui'
upload: "Lataa"
@ -3037,7 +3041,7 @@ fi:
moderator: "Valvoja?"
admin: "Ylläpitäjä?"
blocked: "Estetty?"
staged: "Luotu?"
staged: "Esikäyttäjä?"
show_admin_profile: "Ylläpito"
refresh_browsers: "Pakota sivun uudelleen lataus"
refresh_browsers_message: "Sanoma lähetettiin kaikille päätelaitteille!"
@ -3112,7 +3116,7 @@ fi:
deactivate_explanation: "Käytöstä poistetun käyttäjän täytyy uudelleen vahvistaa sähköpostiosoitteensa."
suspended_explanation: "Hyllytetty käyttäjä ei voi kirjautua sisään."
block_explanation: "Estetty käyttäjä ei voi luoda viestejä tai ketjuja."
staged_explanation: "Automaattisesti luotu käyttäjä voi kirjoittaa vain tiettyihin ketjuihin sähköpostin välityksellä."
staged_explanation: "Esikäyttäjä voi kirjoittaa vain tiettyihin ketjuihin sähköpostin välityksellä."
bounce_score_explanation:
none: "Tästä sähköpostiosoitteesta ei ole tullut palautuksia viime aikoina"
some: "Tästä sähköpostiosoitteesta on tullut joitakin palautuksia viime aikoina"

View File

@ -2369,8 +2369,9 @@ fr:
by: "par"
flags:
title: "Signalements"
old: "Anciens"
active: "Actifs"
active_posts: "Messages signalés"
old_posts: "Anciens messages signalés"
topics: "Sujets signalés"
agree: "Accepter"
agree_title: "Confirmer que le signalement est valide et correcte"
agree_flag_modal_title: "Accepter et…"
@ -2398,6 +2399,8 @@ fr:
clear_topic_flags: "Terminer"
clear_topic_flags_title: "Ce sujet a été étudié et les problèmes ont été résolus. Cliquez sur Terminer pour enlever les signalements."
more: "(plus de réponses…)"
suspend_user: "Suspendre l'utilisateur"
suspend_user_title: "Suspendre l'utilisateur pour ce message"
dispositions:
agreed: "accepté"
disagreed: "refusé"
@ -2408,11 +2411,18 @@ fr:
system: "Système"
error: "Quelque chose s'est mal passé"
reply_message: "Répondre"
no_results: "Il n'y a aucun signalement."
no_results: "Il n'y a pas de messages signalés."
topic_flagged: "Ce <strong>sujet</strong> a été signalé."
show_full: "afficher le message complet"
visit_topic: "Consulter le sujet pour intervenir"
was_edited: "Le message a été modifié après le premier signalement"
previous_flags_count: "Ce message a déjà été signalé {{count}} fois."
show_details: "Afficher les détails du signalement"
flagged_topics:
topic: "Sujet"
type: "Type"
users: "Utilisateurs"
last_flagged: "Dernier signalés"
summary:
action_type_3:
one: "hors sujet"
@ -2950,6 +2960,7 @@ fr:
form:
label: 'Nouveau mot :'
placeholder: 'mot complet ou * comme signe générique'
placeholder_regexp: "expression régulière"
add: 'Ajouter'
success: 'Succès'
upload: "Envoyer"
@ -3011,10 +3022,15 @@ fr:
suspend_failed: "Il y a eu un problème pendant la suspension de cet utilisateur {{error}}"
unsuspend_failed: "Il y a eu un problème pendant le retrait de la suspension de cet utilisateur {{error}}"
suspend_duration: "Combien de temps l'utilisateur sera suspendu ?"
suspend_duration_units: "(jours)"
suspend_reason_label: "Pourquoi suspendez-vous ? Ce texte <b>sera visible par tout le monde</ b> sur la page du profil de cet utilisateur, et sera affiché à l'utilisateur quand ils essaient de se connecter. Soyez bref."
suspend_reason_hidden_label: "Pourquoi le suspendez-vous ? Ce texte sera affiché à l'utilisateur quand il essaie de se connecter. Soyez bref."
suspend_reason: "Raison"
suspend_reason_placeholder: "Raison de la suspension"
suspend_message: "Message courriel"
suspend_message_placeholder: "Donner plus d'informations au sujet de la suspension qui seront envoyées à l'utilisateur par courriel."
suspended_by: "Suspendu par"
suspended_until: "(jusqu'à %{until})"
cant_suspend: "Cet utilisateur ne peut pas être suspendu."
delete_all_posts: "Supprimer tous les messages"
delete_all_posts_confirm_MF: "Vous êtes sur le point de supprimer {POSTS, plural, one {1 message} other {# messages}} et {TOPICS, plural, one {1 sujet} other {# sujets}}. Êtes-vous sûr ?"
suspend: "Suspendre"

View File

@ -540,6 +540,7 @@ it:
admin_tooltip: "Questo utente è un amministratore"
blocked_tooltip: "Questo utente è bloccato"
suspended_notice: "Questo utente è sospeso fino al {{date}}."
suspended_permanently: "Questo utente è sospeso."
suspended_reason: "Motivo: "
github_profile: "Github"
email_activity_summary: "Riassunto Attività"
@ -1415,7 +1416,9 @@ it:
later_this_week: "Più tardi questa settimana"
this_weekend: "Questo fine settimana"
next_week: "La prossima settimana"
two_weeks: "Due Settimane"
next_month: "Il prossimo mese"
forever: "Per sempre"
pick_date_and_time: "Scegli la data e l'ora"
set_based_on_last_post: "Chiudi in base all'ultimo messaggio"
publish_to_category:
@ -2956,6 +2959,7 @@ it:
form:
label: 'Nuova Parola:'
placeholder: 'parola completa o * come carattere jolly'
placeholder_regexp: "espressione regolare"
add: 'Aggiungi'
success: 'Successo'
upload: "Carica"

View File

@ -44,17 +44,17 @@ ja:
less_than_x_seconds:
other: "%{count}秒未満"
x_seconds:
other: "%{count}秒"
other: "%{count}秒"
x_minutes:
other: "%{count}分"
other: "%{count}分"
about_x_hours:
other: "%{count}時間"
other: "%{count}時間"
x_days:
other: "%{count}日"
other: "%{count}日"
about_x_years:
other: "%{count}年"
other: "%{count}年"
over_x_years:
other: "%{count}年以上"
other: "%{count}年以上"
almost_x_years:
other: "約%{count}年"
date_month: "MMM Do"
@ -1630,6 +1630,8 @@ ja:
yes_value: "はい"
via_email: "メールで投稿されました。"
whisper: "この投稿はモデレーターへのプライベートメッセージです"
wiki:
about: "この投稿はWiki形式です"
archetypes:
save: '保存オプション'
controls:
@ -2160,6 +2162,8 @@ ja:
clear_topic_flags: "完了"
clear_topic_flags_title: "このトピックについての問題が解決されました。「完了」をクリックして通報の対応を完了します。"
more: "(more replies...)"
suspend_user: "ユーザを凍結"
suspend_user_title: "この投稿においてユーザを凍結"
dispositions:
agreed: "賛成しました。"
disagreed: "反対する"
@ -2170,7 +2174,7 @@ ja:
system: "システム"
error: "何らかの理由でうまくいきませんでした"
reply_message: "返信する"
no_results: "通報はありません。"
no_results: "通報された投稿はありません。"
topic_flagged: "この <strong>トピック</strong> は通報されました。"
visit_topic: "トピックを確認"
was_edited: "最初の通報後に編集された投稿"
@ -2284,6 +2288,8 @@ ja:
without_uploads: "はい(ファイルは含まない)"
download:
label: "ダウンロード"
title: "ダウンロードリンクをメールで送る"
alert: "バックアップのダウンロードリンクがメールで送られました。"
destroy:
title: "バックアップを削除"
confirm: "このバックアップを削除しますか?"
@ -2329,8 +2335,25 @@ ja:
subject: "件名"
multiple_subjects: "このメールのテンプレートは複数の件名があります。"
none_selected: "編集するメールテンプレートを選択してください。"
revert: "変更を元に戻す"
theme:
edit: "編集"
desktop: "デスクトップ"
mobile: "モバイル"
preview: "プレビュー"
upload: "アップロード"
license: "ライセンス"
check_for_updates: "アップデートを確認"
updating: "アップデート中..."
scss:
text: "CSS"
head_tag:
text: "</head>"
body_tag:
text: "</body>"
colors:
title: "カラー"
edit: "カラースキームの編集"
long_title: "カラースキーム"
new_name: "カラースキームを作成"
copy_name_prefix: "のコピー"
@ -2416,6 +2439,9 @@ ja:
subject: "件名"
body: "本文"
filters:
from_placeholder: "from@example.com"
to_placeholder: "to@example.com"
cc_placeholder: "cc@example.com"
subject_placeholder: "件名..."
error_placeholder: "エラー"
logs:
@ -2488,7 +2514,12 @@ ja:
revoke_admin: "管理者権限を剥奪"
grant_moderation: "モデレータ権限を付与"
revoke_moderation: "モデレータ権限を剥奪"
backup_create: "バックアップを生成"
deleted_tag: "タグを削除"
renamed_tag: "タグ名変更"
change_readonly_mode: "閲覧専用モードに変更する"
backup_download: "バックアップをダウンロード"
backup_destroy: "バックアップを消去"
screened_emails:
title: "ブロック対象アドレス"
description: "新規アカウント作成時、次のメールアドレスからの登録をブロックする。"
@ -2529,6 +2560,7 @@ ja:
flag: 'これらの言葉を含む投稿を許可しますが、仲裁者がこれをレビューできるよう、不適切であると通報されます。'
form:
label: '新しい単語:'
placeholder_regexp: "正規表現"
add: '追加'
success: '成功'
upload: "アップロード"
@ -2586,9 +2618,9 @@ ja:
suspend_failed: "ユーザの凍結に失敗しました: {{error}}"
unsuspend_failed: "ユーザの凍結解除に失敗しました: {{error}}"
suspend_duration: "ユーザを何日間凍結しますか?"
suspend_duration_units: "(日)"
suspend_reason_label: "アカウントを凍結する理由を説明してください。ここに書いた理由は、このユーザのプロファイルページにおいて<b>全員が閲覧可能な状態</b>で公開されます。またこのユーザがログインを試みた際にも表示されます。"
suspend_reason: "理由"
suspend_reason_placeholder: "凍結理由"
suspended_by: "凍結したユーザ"
delete_all_posts: "全ての投稿を削除"
suspend: "凍結"

View File

@ -345,6 +345,11 @@ ko:
closed_group: 닫힌 그룹
is_group_user: "당신은 이 그룹의 구성원입니다."
allow_membership_requests: "사용자가 그룹 소유자에게 가입신청을 할 수 있도록 허용합니다"
membership_request_template: "가입 요청을 전송할 때 사용자에게 표시할 커스텀 템플릿"
membership_request:
submit: "요청 보내기"
title: "@%{group_name}에 가입 요청하기"
reason: "그룹 소유자에게 왜 이 그룹에 속해야하는지 알립니다."
membership: "회원제"
name: "이름"
user_count: "멤버 수"
@ -506,7 +511,8 @@ ko:
admin_tooltip: "이 회원은 관리자입니다."
blocked_tooltip: "이 회원은 차단되었습니다"
suspended_notice: "이 회원은 {{date}}까지 접근 금지 되었습니다."
suspended_reason: "이유: "
suspended_permanently: "이 회원은 일시정지되었습니다."
suspended_reason: "사유: "
github_profile: "Github"
email_activity_summary: "활동 요약"
mailing_list_mode:
@ -990,6 +996,7 @@ ko:
alt: 'Alt'
select_box:
default_header_text: 선택...
no_content: 검색 결과가 없습니다
filter_placeholder: 검색...
emoji_picker:
filter_placeholder: 이모지 찾기
@ -1154,6 +1161,8 @@ ko:
searching: "검색중..."
post_format: "#{{post_number}} by {{username}}"
results_page: "검색 결과"
search_google_button: "Google"
search_google_title: "이 사이트 검색"
context:
user: "@{{username}}의 글 검색"
category: "#{{category}} 카테고리에서 검색"
@ -1185,6 +1194,7 @@ ko:
seen: 읽은 것
unseen: 읽지 않은 것
wiki: 은(는) 위키입니다.
images: 이미지 포함
all_tags: 모든 태그를 포함
statuses:
label: 토픽 조건
@ -2220,8 +2230,7 @@ ko:
by: "에 의해"
flags:
title: "신고"
old: "지난"
active: "활성화된"
active_posts: "신고된 포스트"
agree: "동의"
agree_title: "이 신고가 올바르고 타당함을 확인합니다"
agree_flag_modal_title: "동의 및 ..."
@ -2249,6 +2258,7 @@ ko:
clear_topic_flags: "완료"
clear_topic_flags_title: "주제 조사를 끝냈고 이슈를 해결했습니다. 신고를 지우기 위해 완료를 클릭하세요"
more: "(더 많은 답글...)"
suspend_user: "정지된 사용자"
dispositions:
agreed: "동의"
disagreed: "반대"

View File

@ -540,6 +540,7 @@ nb_NO:
admin_tooltip: "Denne brukeren er en administrator"
blocked_tooltip: "Denne brukeren er blokkert"
suspended_notice: "Denne brukeren er bannlyst til {{date}}."
suspended_permanently: "Brukeren er bannlyst."
suspended_reason: "Begrunnelse:"
github_profile: "Github"
email_activity_summary: "Oppsummering av aktivitet"
@ -1409,13 +1410,17 @@ nb_NO:
remove: "Fjern utløp"
publish_to: "Publiser til:"
when: "Når:"
public_timer_types: Emneutløp
private_timer_types: Brukerstyrte emneutløp
auto_update_input:
later_today: "Senere i dag"
tomorrow: "I morgen"
later_this_week: "Senere denne uken"
this_weekend: "Denne uken"
next_week: "Neste uke"
two_weeks: "To uker"
next_month: "Neste måned"
forever: "For alltid"
pick_date_and_time: "Velg dato og tid"
set_based_on_last_post: "Lukk basert på siste post"
publish_to_category:

View File

@ -2578,8 +2578,9 @@ pl_PL:
by: "przez"
flags:
title: "Flagi"
old: "Stare"
active: "Aktywność"
active_posts: "Ofllagowane wpisy"
old_posts: "Stare oflagowane wpisy"
topics: "Oflagowane tematy"
agree: "Potwierdź"
agree_title: "Potwierdź to zgłoszenie jako uzasadnione i poprawne"
agree_flag_modal_title: "Potwierdź i…"
@ -2607,6 +2608,8 @@ pl_PL:
clear_topic_flags: "Zrobione"
clear_topic_flags_title: "Ten temat został sprawdzony i związane z nim problemy zostały rozwiązane. Kliknij Zrobione, aby usunąć flagi."
more: "(więcej odpowiedzi…)"
suspend_user: "Zawieszony użytkownik"
suspend_user_title: "Zawieś użytkownika za ten wpis"
dispositions:
agreed: "potwierdzono"
disagreed: "wycofano"
@ -2617,11 +2620,18 @@ pl_PL:
system: "System"
error: "Coś poszło nie tak"
reply_message: "Odpowiedz"
no_results: "Nie ma flag."
no_results: "Nie ma żadnych oflagowanych wpisów."
topic_flagged: "Ten <strong>temat</strong> został oflagowany."
show_full: "pokaż cały wpis"
visit_topic: "Odwiedź temat by podjąć działania."
was_edited: "Wpis został zmieniony po pierwszej fladze"
previous_flags_count: "Ten wpis został do tej pory oznaczony flagą {{count}} razy."
show_details: "Pokaż szczegóły oflagowania"
flagged_topics:
topic: "Temat"
type: "Typ"
users: "Użytkownicy"
last_flagged: "Ostatnio Oflagowane"
summary:
action_type_3:
one: "nie-na-temat"
@ -3177,6 +3187,7 @@ pl_PL:
form:
label: 'Nowe słowo:'
placeholder: 'pełne słowo lub jako dzika karta'
placeholder_regexp: "wyrażenie regularne"
add: 'Dodaj'
success: 'Sukces'
upload: "Prześlij"
@ -3246,10 +3257,15 @@ pl_PL:
suspend_failed: "Coś poszło nie tak podczas zawieszania użytkownika {{error}}"
unsuspend_failed: "Coś poszło nie tak podczas odwieszania użytkownika {{error}}"
suspend_duration: "Jak długo użytkownik ma być zawieszony?"
suspend_duration_units: "(dni)"
suspend_reason_label: "Dlaczego zawieszasz? Ten tekst <b>będzie widoczny dla wszystkich</b> na stronie profilu użytkownika i będzie wyświetlany użytkownikowi gdy ten będzie próbował się zalogować. Zachowaj zwięzłość."
suspend_reason_hidden_label: "Dlaczego zawieszasz użytkownika? Ten krótki tekst zostanie wyświetlony, gdy zawieszony użytkownik spróbuje się zalogować. "
suspend_reason: "Powód"
suspend_reason_placeholder: "Powód zawieszenia"
suspend_message: "Wiadomość Email"
suspend_message_placeholder: "Ewentualnie podaj więcej informacji o zawieszeniu użytkownika, a zostaną wysłane do niego poprzez email."
suspended_by: "Zawieszony przez"
suspended_until: "(do %{until})"
cant_suspend: "Nie można zawiesić tego użytkownika."
delete_all_posts: "Usuń wszystkie wpisy"
delete_all_posts_confirm_MF: "Zamierzasz usunąć {POSTS, plural, one {1 post} few {# posty} many {# postów} other {# postów}} i {TOPICS, plural, one {1 temat} few {# tematy} many {# tematów} other {# tematów}}. Czy jesteś pewien?"
suspend: "Zawieś"

View File

@ -1446,6 +1446,8 @@ uk:
change_trust_level: "зміна рівня довіри"
change_username: "зміна імені користувача"
change_site_setting: "зміна налаштування сайта"
change_theme: "змінити тему"
delete_theme: "видалити тему"
change_site_text: "змінити текст сайту"
suspend_user: "призупинення користувача"
unsuspend_user: "скасування призупинення"
@ -1489,6 +1491,15 @@ uk:
ip_address: "IP-адреса"
add: "Додати"
filter: "Пошук"
watched_words:
search: "Пошук"
clear_filter: "Очистити"
actions:
block: 'Заблокувати'
form:
add: 'Додати'
success: 'Успіх'
upload: "Вивантажити"
impersonate:
not_found: "Цього користувача не вдалося знайти."
users:
@ -1496,6 +1507,7 @@ uk:
create: 'Додати адміністратора'
last_emailed: "Останній ел. лист"
not_found: "Даруйте, такого імені користувача немає в нашій системі."
id_not_found: "Даруйте, користувача за таким номером немає в нашій системі."
active: "Активний(а)"
show_emails: "Показати електронну пошту"
nav:

View File

@ -1037,7 +1037,7 @@ ar:
allow_index_in_robots_txt: "حدّد في robots.txt إمكانيّة فهرسة محرّكات البحث في الوبّ هذا الموقع."
email_domains_blacklist: "قائمة pipe-delimited المجالات البريد الإلكتروني الذي لا يسمح للمستخدمين تسجيل حسابات مع. مثال: mailinator.com | trashmail.net"
email_domains_whitelist: "قائمة pipe-delimited من مجالات البريد الإلكتروني التي يجب على المستخدمين تسجيل حسابات مع. تحذير: لن يسمح للمستخدمين مع مجالات البريد الإلكتروني الأخرى غير المذكورة هنا!"
forgot_password_strict: "لا تخبر المستخدمين بوجود الحساب عند استخدامهم حوار نسيان كلمة السّرّ."
hide_email_address_taken: "لا تخبر المستخدمين بوجود الحساب عند استخدامهم حوار نسيان كلمة السّرّ."
log_out_strict: "عند الخروج، اخرج من كلّ جلسات المستخدم في كلّ الأجهزة"
version_checks: "Ping ديسكورس مركزا لتحديثات الإصدار وإظهار الرسائل النسخة الجديدة على لوحة القيادة / مسؤول"
new_version_emails: "إرسال بريد إلكتروني إلى عنوان contact_email عندما نسخة جديدة من ديسكورس هو متاح."

View File

@ -992,7 +992,7 @@ de:
allow_index_in_robots_txt: "Suchmaschinen mittels der robots.txt Datei erlauben, die Site zu indizieren."
email_domains_blacklist: "Eine durch senkrechte Striche getrennte Liste von E-Mail-Domains, die für die Registrierung neuer Konten nicht verwendet werden dürfen. Beispiel: mailinator.com|trashmail.net"
email_domains_whitelist: "Eine durch senkrechte Striche getrennte Liste von E-Mail-Domains, die für die Registrierung neuer Konten verwendet werden können. ACHTUNG: Benutzer mit E-Mail-Adressen anderer Domains werden nicht zugelassen!"
forgot_password_strict: "Benutzer nicht informieren, ob ein Konto existiert, wenn sie den Passwort vergessen-Dialog verwenden."
hide_email_address_taken: "Benutzer nicht informieren, ob ein Konto existiert, wenn sie den Passwort vergessen-Dialog verwenden."
log_out_strict: "Beim Abmelden ALLE Sitzungen des Benutzers auf allen Geräten beenden"
version_checks: "Kontaktiere den Discourse Hub zur Überprüfung auf neue Versionen und zeige Benachrichtigungen über neue Versionen auf der Administratorkonsole an."
new_version_emails: "Sende eine E-Mail an die contact_email Adresse wenn eine neue Version von Discourse verfügbar ist."

View File

@ -57,6 +57,8 @@ el:
topic_closed_error: "Συμβαίνει όταν καταχωρηθεί μία απάντηση για θέμα που έχει κλείσει. "
bounced_email_error: "Το email είναι αναφορά αποτυχίας παράδοσης. "
screened_email_error: "Συμβαίνει όταν η διεύθυνση email του αποστολέα ήταν ήδη ελεγχόμενη"
unsubscribe_not_allowed: "Συμβαίνει όταν η απεγγραφή μέσω email δεν επιτρέπεται για αυτόν τον χρήστη."
email_not_allowed: "Συμβαίνει όταν η διεύθυνση email δεν βρίσκεται στην λευκή ή βρίσκεται στην μαύρη λίστα."
unrecognized_error: "Άγνωστο Σφάλμα"
errors: &errors
format: '%{attribute} %{message}'
@ -979,6 +981,7 @@ el:
gtm_container_id: "Google Tag Manager container id. eg: GTM-ABCDEF"
enable_escaped_fragments: "Επιλογή του Ajax-Crawling API της Google, αν δεν βρεθεί κάποιο πρόγραμμα ανίχνευσης του Ιστού. Βλέπε https://developers.google.com/webmasters/ajax-crawling/docs/learn-more"
allow_moderators_to_create_categories: "Να επιτρέπεται στους συντονιστές να δημιουργούν νέες κατηγορίες"
crawler_user_agents: "Λίστα από user agents τα οποία θεωρούνται crawlers και τους παρέχεται static HTML αντί για JavaScript payload"
cors_origins: "Επιτρεπόμενες πηγές για αιτήσεις πολλαπλής προέλευσης (cross-origin requests, CORS). Η κάθε προέλευση πρέπει να περιέχει http:// or https://. Η env μεταβλητή DISCOURSE_ENABLE_CORS πρέπει να οριστεί σε αληθινή για να ενεργοποιηθεί το CORS."
use_admin_ip_whitelist: "Οι διαχειριστές μπορούν να συνδέονται μόνο αν βρίσκονται σε μια διευθυνση IP καθορισμένη στη λίστα Screened IPs (Admin > Logs > Screened Ips)."
blacklist_ip_blocks: "Μια λίστα από private IP blocks η οποία ποτέ δεν θα ανιχνεύεται από το Discourse"
@ -1007,7 +1010,7 @@ el:
allow_index_in_robots_txt: "Καθόρισε στο robots.txt ότι για αυτή την ιστοσελίδα επιτρέπεται να δημιουργείται κατάλογος περιεχομένων από τις μηχανές αναζήτησης."
email_domains_blacklist: "Μία λίστα με διευθύνσεις email τις οποίες οι χρήστες δεν μπορούν να χρησιμοποιήσουν για να δημιουργήσουν λογαριασμό. Πχ: mailinator.com|trashmail.net"
email_domains_whitelist: "Μία λίστα με διευθύνσεις email τις οποίες οι χρήστες ΘΑ ΠΡΕΠΕΙ να χρησιμοποιήσουν για να δημιουργήσουν λογαριασμό. ΠΡΟΣΟΧΗ: οι χρήστες με διευθύνσεις email οι οποίες δεν βρίσκονται σε αυτή τη λίστα δεν θα μπορούν να δημιουργήσουν λογαριασμό."
forgot_password_strict: "Να μην ενημερώνονται οι χρήστες για την ύπαρξη ενός λογαριασμού όταν χρησιμοποιούν την λειτουργία ανάκτησης κωδικού πρόσβασης."
hide_email_address_taken: "Μην ενημερώνεις του χρήστες ότι υπάρχει λογαριασμός χρήστη με αυτήν την διεύθυνση email κατά την εγγραφή και στην φόρμα επαναφοράς κωδικού."
log_out_strict: "Όταν αποσυνδεθείτε, ΟΛΕΣ οι δραστηριότητες σας σε ΟΛΕΣ τις συσκευές θα αποσυνδεθούν"
version_checks: "Έλεγξε το Hub του Discourse για αναβαθμίσεις και δείξε μηνύματα για νέες ενημερώσεις στην σελίδα διαχείρισης. "
new_version_emails: "Αποστολή email στην contact_email διεύθυνση όταν μια νέα έκδοση του Discourse είναι διαθέσιμη."
@ -1905,6 +1908,13 @@ el:
Λυπούμαστε, αλλά το email σας προς %{destination} (με τίτλο %{former_title}) απέτυχε.
Η απάντησή σας στάλθηκε από μία αποκλεισμένη διεύθυνση email. Δοκιμάστε να στείλετε από κάποια άλλη διεύθυνση email ή [επικοινωνήστε με την διαχείριση](%{base_url}/about).
email_reject_not_allowed_email:
title: "Email Απερρίφθη Μη Επιτρεπτό Email"
subject_template: "[%{email_prefix}] Πρόβλημα Email -- Αποκλεισμένο Email"
text_body_template: |
Λυπούμαστε, αλλά το email προς %{destination} (με τίτλο %{former_title}) δεν λειτούργησε.
Η απάντησή σας στάλθηκε από μία αποκλεισμένη διεύθυνση email. Δοκιμάστε να στείλετε ξανά από κάποια άλλη διεύθυνση email ή [επικοινωνήστε με συνεργάτη](%{base_url}/about).
email_reject_inactive_user:
title: "Απόρριψη email Μη ενεργός χρήστης"
subject_template: "[%{email_prefix}] Πρόβλημα Email -- Ανενεργός Χρήστης"
@ -2350,6 +2360,9 @@ el:
%{reason}
%{message}
account_exists:
title: "Ο λογαριασμός υπάρχει ήδη"
subject_template: "[%{email_prefix}] Ο λογαριασμός υπάρχει ήδη"
digest:
why: "Μια σύντομη σύνοψη του %{site_link} από την τελευταία σου επίσκεψη στις %{last_seen_at}"
since_last_visit: "Από την τελευταία σου επίσκεψη"

View File

@ -79,6 +79,8 @@ en:
topic_closed_error: "Happens when a reply came in but the related topic has been closed."
bounced_email_error: "Email is a bounced email report."
screened_email_error: "Happens when the sender's email address was already screened."
unsubscribe_not_allowed: "Happens when unsubscribing via email is not allowed for this user."
email_not_allowed: "Happens when the email address is not on the whitelist or is on the blacklist."
unrecognized_error: "Unrecognized Error"
errors: &errors
@ -1063,6 +1065,7 @@ en:
gtm_container_id: "Google Tag Manager container id. eg: GTM-ABCDEF"
enable_escaped_fragments: "Fall back to Google's Ajax-Crawling API if no webcrawler is detected. See https://developers.google.com/webmasters/ajax-crawling/docs/learn-more"
allow_moderators_to_create_categories: "Allow moderators to create new categories"
crawler_user_agents: "List of user agents that are considered crawlers and served static HTML instead of JavaScript payload"
cors_origins: "Allowed origins for cross-origin requests (CORS). Each origin must include http:// or https://. The DISCOURSE_ENABLE_CORS env variable must be set to true to enable CORS."
use_admin_ip_whitelist: "Admins can only log in if they are at an IP address defined in the Screened IPs list (Admin > Logs > Screened Ips)."
blacklist_ip_blocks: "A list of private IP blocks that should never be crawled by Discourse"
@ -1094,7 +1097,7 @@ en:
allow_index_in_robots_txt: "Specify in robots.txt that this site is allowed to be indexed by web search engines."
email_domains_blacklist: "A pipe-delimited list of email domains that users are not allowed to register accounts with. Example: mailinator.com|trashmail.net"
email_domains_whitelist: "A pipe-delimited list of email domains that users MUST register accounts with. WARNING: Users with email domains other than those listed will not be allowed!"
forgot_password_strict: "Don't inform users of an account's existence when they use the forgot password dialog."
hide_email_address_taken: "Don't inform users that an account exists with a given email address during signup and from the forgot password form."
log_out_strict: "When logging out, log out ALL sessions for the user on all devices"
version_checks: "Ping the Discourse Hub for version updates and show new version messages on the /admin dashboard"
new_version_emails: "Send an email to the contact_email address when a new version of Discourse is available."
@ -2149,6 +2152,14 @@ en:
Your reply was sent from a blocked email address. Try sending from another email address, or [contact a staff member](%{base_url}/about).
email_reject_not_allowed_email:
title: "Email Reject Not Allowed Email"
subject_template: "[%{email_prefix}] Email issue -- Blocked Email"
text_body_template: |
We're sorry, but your email message to %{destination} (titled %{former_title}) didn't work.
Your reply was sent from a blocked email address. Try sending from another email address, or [contact a staff member](%{base_url}/about).
email_reject_inactive_user:
title: "Email Reject Inactive User"
subject_template: "[%{email_prefix}] Email issue -- Inactive User"
@ -2645,6 +2656,19 @@ en:
%{message}
account_exists:
title: "Account already exists"
subject_template: "[%{email_prefix}] Account already exists"
text_body_template: |
You just tried to create an account at %{site_name}, or tried to change the email of an account to %{email}. However, an account already exists for %{email}.
If you forgot your password, [reset it now](%{base_url}/password-reset).
If you didnt try to create an account for %{email} or change your email address, dont worry you can safely ignore this message.
If you have any questions, [contact our friendly staff](%{base_url}/about).
digest:
why: "A brief summary of %{site_link} since your last visit on %{last_seen_at}"

View File

@ -971,7 +971,7 @@ es:
allow_index_in_robots_txt: "Especificar en robots.txt que este sitio puede ser indexado por los motores de búsqueda web."
email_domains_blacklist: "Una lista de dominios de correo electrónico con los que los usuarios no se podrán registrar. Ejemplo: mailinator.com|trashmail.net"
email_domains_whitelist: "Una lista de dominios de email con los que los usuarios DEBERÁN registrar sus cuentas. AVISO: ¡los usuarios con un email con diferente dominio a los listados no estarán permitidos!"
forgot_password_strict: "No informar a los usuarios de la existencia de una cuenta cuando utilicen el diálogo de pérdida de contraseña."
hide_email_address_taken: "No informar a los usuarios de la existencia de una cuenta cuando utilicen el diálogo de pérdida de contraseña."
log_out_strict: "Al cerrar sesión, cierra TODAS las sesiones del usuario en todos los dispositivos"
version_checks: "Ping el 'Discourse Hub' para actualizaciones de versión y mostrar mensajes del número de versión en el dashboard /admin"
new_version_emails: "Enviar un email a la dirección contact_email cuando esté disponible una nueva versión de Discourse."

View File

@ -929,7 +929,7 @@ fa_IR:
allow_index_in_robots_txt: "در robots.txt که به این سایت اجازه دهید که در موتور‌های جستجو ایندکس شود."
email_domains_blacklist: "لیست pipe-delimit دامنه های ایمیل که کاربران اجازه ندارند با آن حساب کاربری ثبت‌نام کنند. برای مثال: mailinator.com|trashmail.net"
email_domains_whitelist: "لیست pipe-delimit دامنه های ایمیل که کاربران اجازه باید با آن حساب کاربری ثبت نام کنند. اخطار: کاربرانی با دامنه‌های ایمیلی به غیر از آن‌هایی که در لیست هستند اجازه ندارند. "
forgot_password_strict: "آگاه نکردن کاربران از وجود حساب کاربری در صفحه فراموشی روز عبور"
hide_email_address_taken: "آگاه نکردن کاربران از وجود حساب کاربری در صفحه فراموشی روز عبور"
log_out_strict: "وقتی از سیستم خارج می شود، کاربر را از تمام sessionها بر روی تمام دستگاه‌ها خارج کن "
version_checks: "Discourse Hub را پینگ کن برای نسخه بروزرسانی و پیام نسخه جدید را صفحه آمار ادمین نشان بده."
new_version_emails: "ارسال ایمیل به contact_email address وقتی نسخه جدید Discourse موجود است. "

View File

@ -40,7 +40,7 @@ fi:
incoming:
default_subject: "Tämä ketju tarvitsee otsikon"
show_trimmed_content: "Näytä piilotettu sisältö"
maximum_staged_user_per_email_reached: "Saavutti maksimimäärän automaattisesti luotuja tunnuksia per sähköpostiosoite"
maximum_staged_user_per_email_reached: "Saavutti maksimimäärän automaattisesti luotuja esikäyttäjiä per sähköpostiosoite."
errors:
empty_email_error: "Näin käy, kun saapuneessa sähköpostissa ei lue mitään."
no_message_id_error: "Näin käy, kun viestin otsikkotiedoista puuttuu ID-tunniste (engl. message-ID)."
@ -57,6 +57,7 @@ fi:
topic_closed_error: "Näin käy, kun vastauksen saapuessa ketju, johon viesti oli tarkoitettu, on suljettu."
bounced_email_error: "Sähköposti on palautetun sähköpostin raportti"
screened_email_error: "Näin käy, kun lähettäjän sähköpostiosoite on jo seulottu."
email_not_allowed: "Näin käy, kun sähköpostiosoite ei ole sallittujen listalla tai on kiellettyjen listalla."
unrecognized_error: "Tuntematon virhe"
errors: &errors
format: '%{attribute} %{message}'
@ -567,7 +568,7 @@ fi:
confirmed: "Sähköpostiosoite päivitetty."
please_continue: "Jatka sivustolle %{site_name}"
error: "Sähköpostiosoitteen vaihdossa tapahtui virhe. Ehkäpä tämä sähköpostiosoite on jo käytössä?"
error_staged: "Sähköpostiosoitetta muutettaessa tapahtui virhe. Osoite on automaattisesti luodun käyttäjän käytössä."
error_staged: "Sähköpostiosoitetta muutettaessa tapahtui virhe. Osoite on automaattisesti luodun esikäyttäjän käytössä."
already_done: "Pahoittelut, tämä varmennuslinnkki ei ole enää voimassa. Ehkäpä sähköpostiosoitteesi on jo vaihdettu?"
authorizing_old:
title: "Kiitos sähköpostiosoitteesi varmentamisesta"
@ -635,6 +636,9 @@ fi:
short_description: 'Äänestä viestiä'
long_form: 'viestiä äänestetty'
user_activity:
no_default:
self: "Et ole vielä tehnyt mitään mainittavaa."
others: "Ei ole tehnyt mitään mainittavaa."
no_bookmarks:
self: "Kirjanmerkeissäsi ei ole viestejä. Kirjanmerkit auttavat löytämään viestejä helposti myöhemmin."
others: "Ei kirjanmerkkejä."
@ -965,6 +969,7 @@ fi:
gtm_container_id: "Google Tag Manager -säiliön ID. Esim: GTM-ABCDEF"
enable_escaped_fragments: "Käytä Googlen Ajax-sivustoille tarkoitettua API:a, jos webcrawleria ei tunnisteta. Katso https://developers.google.com/webmasters/ajax-crawling/docs/learn-more"
allow_moderators_to_create_categories: "Salli valvojien luoda uusia alueita"
crawler_user_agents: "Lista käyttäjäagenteista, joita pidetään hakurobotteina ja joille näytetään staattinen HTML-sivu JavaScript-tietosisällön sijaan"
cors_origins: "Salli lähteet CORS-pyynnöille (cross-origin request). Jokaisen lähteen pitää sisältää http:// tai https://. DISCOURSE_ENABLE_CORS asetus pitää olla valittuna ottaaksesi CORSin käyttöön."
use_admin_ip_whitelist: "Ylläpitäjät voivat kirjautua vain IP-osoitteista, jotka on määritetty Seulottavien IP:iden listassa (Ylläpito > Lokit > Seulottavat IP:t)"
blacklist_ip_blocks: "Lista yksityisistä IP-blokeista, joita Discoursen ei tule käydä läpi"
@ -991,7 +996,7 @@ fi:
allow_index_in_robots_txt: "Määrittele robots.txt-tiedostossa, että hakukoneet saavat luetteloida sivuston."
email_domains_blacklist: "Pystyviivalla eroteltu lista sähköposti-verkkotunnuksista, joista käyttäjät eivät voi luoda tiliä. Esimerkiksi mailinator.com|trashmail.net"
email_domains_whitelist: "Pystyviivalla eroteltu lista sähköposti-verkkotunnuksista, joista käyttäjien pitää luoda tilinsä. VAROITUS: Käyttäjiä, joiden sähköpostiosoite on muusta verkkotunnuksesta ei sallita!"
forgot_password_strict: "Älä paljasta tilin olemassaoloa unohtuneen salasanan kyselyssä."
hide_email_address_taken: "Älä kerro käyttäjälle, että käyttäjätili annetulla sähköpostiosoitteella on jo olemassa, kun hän liittyy palstalle tai kun hän pyytää salasanan palauttamista."
log_out_strict: "Kun kirjaudutaan ulos, kirjaa käyttäjä ulos kaikilta laitteilta"
version_checks: "Pingaa Discourse Hubia päivityksistä ja näytä viesti /admin hallintapaneelissa kun uusi versio on saatavilla"
new_version_emails: "Lähetä sähköposti contact_email osoitteeseen kun uusi versio Discoursesta on saatavilla."
@ -1093,6 +1098,7 @@ fi:
allow_all_attachments_for_group_messages: "Salli kaikki sähköpostiliitteet ryhmäviesteissä."
png_to_jpg_quality: "Muunnetun JPG-tiedoston laatu (1 on huonoin laatu, 99 on paras laatu, 100 ottaa pois käytöstä)."
allow_staff_to_upload_any_file_in_pm: "Salli henkilökunnan ladata minkätyyppisiä liitteitä tahansa yksityisviesteihin."
strip_image_metadata: "Poista metadata kuvista."
enable_flash_video_onebox: "Ota käyttöön swf- ja flv-linkkien (Adobe Flash) onebox-tuki. VAROITUS: saattaa lisätä tietoturvariskejä."
default_invitee_trust_level: "Oletus luottamustaso (0-4) kutsutuille käyttäjille."
default_trust_level: "Uusien käyttäjien oletusarvoinen luottamustaso (0-4). VAROITUS! Tämän muuttaminen altistaa roskapostille."
@ -1125,6 +1131,7 @@ fi:
min_trust_to_edit_post: "Viestin muokkaamiseen vaadittava luottamustaso."
min_trust_to_allow_self_wiki: "Minimiluottamustaso, jolla käyttäjä voi tehdä omasta viestistään wiki-viestin."
min_trust_to_send_messages: "Yksityisviestien luomiseen vaadittava luottamustaso"
min_trust_to_send_email_messages: "Vähimmäisluottamustaso, jotta voi lähettää uusia yksityisviestejä sähköpostilla (esikäyttäjille)"
newuser_max_links: "Kuinka monta linkkiä uusi käyttäjä voi lisätä viestiin."
newuser_max_images: "Kuinka monta kuvaa uusi käyttäjä voi lisätä viestiin."
newuser_max_attachments: "Kuinka monta liitettä uusi käyttäjä voi lisätä viestiin."
@ -1199,8 +1206,8 @@ fi:
unsubscribe_via_email_footer: "Liitä sähköpostiviestien alaosaan mailto: linkki, jonka avulla saaja voi lakkauttaa sähköposti-ilmoitukset"
delete_email_logs_after_days: "Poista sähköpostilokit (N) päivän jälkeen. Aseta 0 säilyttääksesi ikuisesti."
max_emails_per_day_per_user: "Käyttäjälle päivässä lähetettävien sähköpostien enimmäismäärä. Aseta 0, jos et halua rajoittaa."
enable_staged_users: "Luo automaattisesti käyttäjiä, kun saapuvia sähköposteja käsitellään."
maximum_staged_users_per_email: "Maksimimäärä automaattisesti luotavia tilejä, kun käsitellään saapuvaa sähköpostia."
enable_staged_users: "Luo automaattisesti esikäyttäjiä, kun saapuvia sähköposteja käsitellään."
maximum_staged_users_per_email: "Enimmäismäärä automaattisesti luotuja esikäyttäjiä, kun käsitellään saapuvaa sähköpostia."
auto_generated_whitelist: "Lista sähköpostiosoitteista, joiden viestejä ei tarkasteta automaattisesti luodun sisällön osalta. Esimerkki: foo@bar.com|discourse@bar.com"
block_auto_generated_emails: "Estä saapuvat sähköpostit, jotka tunnistetaan automaattisesti luoduiksi."
ignore_by_title: "Jätä sähköpostit huomiotta niiden otsikon perusteella."
@ -1260,6 +1267,7 @@ fi:
anonymous_posting_min_trust_level: "Anonyymin tilan käyttämiseen vaadittava luottamustila"
anonymous_account_duration_minutes: "Suojellaksesi anonymiteettiä, luo uusi anonyymi tili N minuutin välein jokaiselle käyttäjälle. Esimerkki: jos arvoksi asetetaan 600, kun 600 minuuttia tulee kuluneeksi edellisestä viestistä JA käyttäjä vaihtaa anonyymiin tilaan, luodaan uusi anonyymi tili."
hide_user_profiles_from_public: "Älä näytä käyttäjäkortteja, käyttäjäprofiileita tai käyttäjähakemistoa kirjautumattomille käyttäjille."
hide_suspension_reasons: "Älä näytä hyllytysten syitä julkisesti käyttäjäprofiileissa."
user_website_domains_whitelist: "Käyttäjän kotisivu voi olla näiden verkkotunnusten alainen. Pystyviivoin erotettu lista."
allow_profile_backgrounds: "Salli käyttäjien ladata profiilin taustakuva."
sequential_replies_threshold: "Kuinka monen peräkkäisen viestin jälkeen yhdessä ketjussa käyttäjää muistutetaan peräkkäisistä vastauksista."
@ -1276,6 +1284,7 @@ fi:
topic_page_title_includes_category: "Ketjusivu sisältää alueen nimen."
native_app_install_banner: "Tarjoaa toistuvasti vieraileville Discoursen käyttöjärjestelmäkohtaista sovellusta."
share_anonymized_statistics: "Julkaise yksilöimättömät käyttötilastot."
auto_handle_queued_age: "Käsittele automaattisesti asiat, jotka ovat odottaneet käsittelyä näin monta päivää. Lippuja lykätään. Jonossa olevat viestit ja käyttäjät hylätään. Jos asetat 0:ksi, ominaisuus ei ole käytössä."
max_prints_per_hour_per_user: "Tulostuspyyntöjen (/print) enimmäismäärä (aseta 0 poistaaksesi käytöstä)"
full_name_required: "Koko nimi on käyttäjäprofiilin vaadittu kohta"
enable_names: "Näytä käyttäjän koko nimi profiilissa, käyttäjäkortissa ja sähköposteissa. Poista käytöstä piilottaaksesi koko nimen kaikkialla."
@ -1307,6 +1316,7 @@ fi:
auto_close_topics_post_count: "Maksimimäärä viestejä ketjussa, kunnes se suljetaan automaattisesti (0 poistaaksesi käytöstä)"
code_formatting_style: "Viestikentän koodipainike käyttää oletuksena tätä koodimuotoilutyyliä"
max_allowed_message_recipients: "Kuinka monta vastaanottajaa yksityisviestillä voi olla."
watched_words_regular_expressions: "Tarkkaillut sanat ovat säännöllisiä lausekkeita."
default_email_digest_frequency: "Kuinka usein käyttäjille lähetetään sähköpostikooste oletuksena."
default_include_tl0_in_digests: "Sisällytä uusien käyttäjien viestit sähköpostikoosteisiin oletuksena. Tätä voi muuttaa käyttäjäasetuksissa."
default_email_private_messages: "Lähetä oletuksena sähköposti, kun joku lähettää käyttäjälle viestin."
@ -1377,6 +1387,8 @@ fi:
invalid_regex: "Säännöllinen lauseke ei kelpaa tai ei ole sallittu."
email_editable_enabled: "Asetus 'email editable' on otettava pois käytöstä ennen tämän asetuksen käyttöönottoa."
enable_sso_disabled: "Asetus 'enable sso' on otettava käyttöön ennen tämän asetuksen käyttöönottoa."
staged_users_disabled: "\"Esikäyttäjät\" on otettava käyttöön ennen tämän asetuksen käyttöönottoa."
reply_by_email_disabled: "Asetus \"reply by email\" täytyy ottaa käyttöön ennen tämän asetuksen käyttöönottoa."
search:
within_post: "#%{post_number} käyttäjältä %{username}"
types:
@ -1521,6 +1533,7 @@ fi:
max_new_accounts_per_registration_ip: "Rekisteröitymisiä ei oteta vastaan IP-osoitteestasi (maksimimäärä saavutettu). Ota yhteyttä henkilökuntaan."
website:
domain_not_allowed: "Verkkosivu ei kelpaa. Sallitus verkkotunnukset ovat: %{domains}"
auto_rejected: "Hylättiin automaattisesti iän perusteella. Katso auto_handle_queued_age -sivustoasetus."
flags_reminder:
flags_were_submitted:
one: "Viestejä liputettiin yli tunti sitten. [Tarkastele niitä](/admin/flags)."
@ -1875,6 +1888,13 @@ fi:
Vastauksesi lähetettiin estetystä sähköpostiosoitteesta. Yritä lähettää viesti toisesta sähköpostiosoitteesta tai [ota yhteyttä henkilökuntaan](%{base_url}/about).
email_reject_not_allowed_email:
title: "Sähköposti hylätty - osoite ei sallittu"
subject_template: "[%{email_prefix}] Sähköpostiongelma -- Estetty osoite"
text_body_template: |
Pahoittelemme, mutta sähköpostin lähettäminen tänne %{destination} (otsikolla %{former_title}) ei onnistunut.
Vastauksesi on peräisin estetystä sähköpostiosoitteesta. Kokeile lähettää toisesta sähköpostiosoitteesta tai [ota yhteyttä henkilökuntaan](%{base_url}/about).
email_reject_inactive_user:
title: "Sähköposti hylätty - aktivoimaton käyttäjä"
subject_template: "[%{email_prefix}] Sähköpostiongelma -- Aktivoimaton käyttäjä"
@ -1923,9 +1943,17 @@ fi:
email_reject_invalid_access:
title: "Sähköposti hylätty - pääsy estetty"
subject_template: "[%{email_prefix}] Sähköpostiongelma -- Ei pääsyoikeutta"
text_body_template: |
Pahoittelut, sähköpostiviestiäsi tänne: %{destination} (otsikolla %{former_title}) ei voitu toimittaa.
Käyttäjätililläsi ei ole oikeutta luoda ketjua sille alueelle. Jos uskot, että tämä johtuu virheestä, [ota yhteyttä henkilökuntaan](%{base_url}/about).
email_reject_strangers_not_allowed:
title: "Sähköposti hylätty - vierailla ei pääsyä"
subject_template: "[%{email_prefix}] Sähköpostiongelma -- Ei pääsyoikeutta"
text_body_template: |
Pahoittelut, sähköpostiviestisi lähetys kohteeseen %{destination} (otsikolla %{former_title}) ei onnistunut.
Alueelle jolle lähetit viestin voivat kirjoittaa ne, joilla on käypä käyttäjätunnus ja sähköpostiosoite. Jos uskot, että tämä johtuu virheestä, [ota yhteyttä henkilökuntaan](%{base_url}/about).
email_reject_invalid_post:
title: "Sähköposti hylätty - viesti ei kelpaa"
subject_template: "[%{email_prefix}] Sähköpostiongelma -- Lähetysvirhe"
@ -1954,18 +1982,41 @@ fi:
email_reject_reply_key:
title: "Sähköposti hylätty - vastausavain"
subject_template: "[%{email_prefix}] Sähköpostiongelma -- Tuntematon vastausavain"
text_body_template: |
Pahoittelut, sähköpostiviestisi lähetys kohteeseen %{destination} (titled %{former_title}) ei onnistunut.
Sähköpostiviestin vastaustunniste, engl. 'reply key', ei ole kelvollinen, minkä vuoksi ei tiedetä, mihin asiaan viestisi oli tarkoitus vastata. [Ota yhteyttä henkilökuntaan](%{base_url}/about).
email_reject_bad_destination_address:
title: "Sähköposti hylätty - tuntematon vastaanottajaosoite"
subject_template: "[%{email_prefix}] Sähköpostiongelma -- Tuntematon Vastaanottaja: -osoite"
email_reject_topic_not_found:
title: "Sähköposti hylätty - ketjua ei löytynyt"
subject_template: "[%{email_prefix}] Sähköpostiongelma -- Ketjua ei löytynyt"
text_body_template: |
Pahoittelut, sähköpostiviestisi lähetys kohteeseen %{destination} (otsikolla %{former_title}) ei onnistunut.
Ketjua johon yritit kirjoittaa ei ole enää olemassa -- ehkä se poistettiin? Jos uskot, että tämä johtuu virheestä, [ota yhteyttä henkilökuntaan](%{base_url}/about).
email_reject_topic_closed:
title: "Sähköposti hylätty - ketju suljettu"
subject_template: "[%{email_prefix}] Sähköpostiongelma -- Suljettu ketju"
text_body_template: |
Pahoittelut, sähköpostiviestiäsi tänne: %{destination} (otsikolla %{former_title}) ei voitu toimittaa.
Ketju, johon yritit vastata on tällä hetkellä suljettu, eikä siihen voi enää vastata. Jos uskot, että tämä johtuu virheestä, [ota yhteyttä henkilökuntaan](%{base_url}/about).
email_reject_auto_generated:
title: "Sähköposti hylätty - automaattivastaus"
subject_template: "[%{email_prefix}] Sähköpostiongelma -- Automaattivastaus"
text_body_template: |
Pahoittelut, sähköpostiviestisi lähetys kohteeseen %{destination} (otsikolla %{former_title}) ei onnistunut.
Järjestelmä havaitsi viestisi olevan tietokoneen automaattisesti luoma eikä ihmisen kirjoittama, eikä viestiä voitu siksi hyväksyä. Jos uskot, että tämä johtuu virheestä, [ota yhteyttä henkilökuntaan](%{base_url}/about).
email_reject_unrecognized_error:
title: "Sähköposti hylätty - Tunnistamaton virhe"
subject_template: "[%{email_prefix}] Sähköpostiongelma -- Tunnistamaton virhe"
text_body_template: |
Pahoittelut, sähköpostiviestisi lähetys kohteeseen %{destination} (otsikolla %{former_title}) ei onnistunut.
Viestiäsi käsiteltäessä tapahtui tunnistamaton virhe eikä sitä siksi julkaistu. Kokeile uudelleen tai [ota yhteyttä henkilökuntaan](%{base_url}/about).
email_error_notification:
title: "Ilmoitus sähköpostivirheestä"
subject_template: "[%{email_prefix}] Sähköpostiongelma -- virhe POP-autentikoinnissa"
@ -2068,6 +2119,15 @@ fi:
Palkinto myönnetään vain kahdelle käyttäjälle joka kuukausi, ja se näkyy pysyvästi [käyttäjäsivullasi](%{base_url}/my/badges).
Sinusta on äkkiä tullut tärkeä osa yhteisöä. Kiitos kun liityit, ja jatka samaa rataa!
queued_posts_reminder:
title: "Muistutukset jonossa olevista viesteistä"
subject_template:
one: "Yksi viesti odottaa tarkastusta"
other: "%{count} viestiä odottaa tarkastusta"
text_body_template: |
Hei
Uusien käyttäjien viestejä odottaa valvojan hyväksyntää. [Hyväksy tai hylkää ne täällä](%{base_url}/queued-posts).
unsubscribe_link: |
Jos et enää halua näitä viestejä, [klikkaa tästä](%{unsubscribe_url}).
unsubscribe_link_and_mail: |
@ -2093,6 +2153,8 @@ fi:
visit_link_to_respond: "[Vieraile ketjussa](%{base_url}%{url}) vastataksesi."
visit_link_to_respond_pm: "[Vieraile ketjussa](%{base_url}%{url}) vastataksesi."
posted_by: "Käyttäjältä %{username} %{post_date}"
user_invited_to_private_message_pm_group:
title: "Ryhmä kutsuttiin yksityiskeskusteluun"
user_invited_to_private_message_pm:
title: "Käyttäjä kutsuttiin yksityiskeskusteluun"
subject_template: "[%{email_prefix}] %{username} kutsui sinut yksityiskeskusteluun '%{topic_title}'"
@ -2225,6 +2287,26 @@ fi:
text_body_template: |2
%{message}
account_suspended:
title: "Tili hyllytetty"
subject_template: "[%{email_prefix}] Tilisi on hyllytetty"
text_body_template: |
Sinut hyllytettiin palstalta %{suspended_till} asti.
%{reason}
%{message}
account_exists:
title: "Tili on jo olemassa"
subject_template: "[%{email_prefix}] TIli on jo olemassa"
text_body_template: |
Yritit luoda tilin sivustolle %{site_name} tai yritit muuttaa tilin sähköpostiosoitteeksi %{email}. Sähköpostiosoitteella %{email} on kuitenkin jo tili olemassa.
Jos unohdit salasanasi, [voit uusia sen nyt](%{base_url}/password-reset).
Jos et yrittänyt luoda tunnusta sähköpostiosoitteella %{email} tai vaihtaa sähköpostiosoitettasi, älä huoli - voit huoletta jättää tämän viestin huomiotta.
Jos sinulla on kysyttävää, [ota yhteyttä avuliaaseen henkilökuntaamme](%{base_url}/about).
digest:
why: "Lyhyt kooste siitä mitä on tapahtunut sivustolla %{site_link} viimeisimmän vierailusi jälkeen %{last_seen_at}."
since_last_visit: "Viime vierailusi jälkeen"
@ -2341,6 +2423,10 @@ fi:
see_more: "Lisää"
search_title: "Etsi tältä sivustolta"
search_google: "Google"
login_required:
welcome_message: |
## [Tervetuloa sivustolle %{title}](#welcome)
Käyttäjätili tarvitaan. Luo tili tai kirjaudu sisään.
terms_of_service:
title: "Käyttöehdot"
signup_form_message: 'Olen lukenut ja ymmärtänyt <a href="/tos" target="_blank">Käyttöehdot</a>.'
@ -2806,6 +2892,18 @@ fi:
description: Erinomaista osallistumista ensimmäisen kuukauden aikana
long_description: |
Tämä ansiomerkki myönnetään kahdelle uudelle käyttäjälle joka kuukausi kiitoksena erinomaisesta osallistumisestaan. Mittari on tykkäykset: kuinka usein viesteistä tykätään ja kuka tykkää.
enthusiast:
name: Intoilija
description: Vieraili 10 päivänä
long_description: Tämä ansiomerkki myönnetään, kun olet vieraillut 10 peräkkäisenä päivänä. Kiitos kun olet ollut kanssamme yli viikon ajan!
aficionado:
name: Hullaantunut
description: Vieraili 100 päivänä
long_description: Tämä ansiomerkki myönnetään, kun olet vieraillut 100 peräkkäisenä päivänä. Sehän on yli kolme kuukautta!
devotee:
name: Omistautunut
description: Vieraili 365 päivänä
long_description: Tämä ansiomerkki myönnetään, kun olet vieraillut 365 peräkkäisenä päivänä. Vau, kokonainen vuosi!
badge_title_metadata: "%{display_name} -ansiomerkki sivustolla %{site_title}"
admin_login:
success: "Sähköposti lähetetty"
@ -2890,6 +2988,7 @@ fi:
description: "Sinun tai organisaatiosi yleinen yhteydenottosivu. Näytetään <a href='/about' target='_blank'>Tietoja-sivulla</a>."
site_contact:
label: "Automaattiset viestit"
description: "Tämän käyttäjän nimissä Discourse lähettää käyttäjille kaikki automaattiset yksityisviestit, kuten liputusvaroitukset ja ilmoitukset valmistuneista varmuuskopioista."
corporate:
title: "Organisaatio"
description: "Nämä nimet näkyvät <a href='/privacy' target='blank'>rekisteriselosteen</a> ja <a href='/tos' target='blank'>käyttöehtojen</a> yhteydessä, joita voit milloin vain muokata henkilökunta-alueella. Jos taustalla ei ole yritystä, voit hypätä tämän vaiheen yli toistaiseksi."

Some files were not shown because too many files have changed in this diff Show More