diff --git a/app/assets/javascripts/admin/routes/admin-customize-themes.js.es6 b/app/assets/javascripts/admin/routes/admin-customize-themes.js.es6
index 24ee2312f3..49a74bc281 100644
--- a/app/assets/javascripts/admin/routes/admin-customize-themes.js.es6
+++ b/app/assets/javascripts/admin/routes/admin-customize-themes.js.es6
@@ -16,8 +16,7 @@ export default Ember.Route.extend({
},
addTheme(theme) {
- const all = this.modelFor("adminCustomizeThemes");
- all.pushObject(theme);
+ this.refresh();
this.transitionTo("adminCustomizeThemes.show", theme.get("id"));
},
diff --git a/app/assets/javascripts/admin/templates/customize-themes-index.hbs b/app/assets/javascripts/admin/templates/customize-themes-index.hbs
index 39bdfc7c85..565d0024db 100644
--- a/app/assets/javascripts/admin/templates/customize-themes-index.hbs
+++ b/app/assets/javascripts/admin/templates/customize-themes-index.hbs
@@ -4,7 +4,7 @@
{{#each externalResources as |resource|}}
-
+
{{d-icon resource.icon}}
{{I18n resource.key}}
diff --git a/app/assets/javascripts/admin/templates/logs/screened-ip-addresses.hbs b/app/assets/javascripts/admin/templates/logs/screened-ip-addresses.hbs
index c5819da791..109e7e32e1 100644
--- a/app/assets/javascripts/admin/templates/logs/screened-ip-addresses.hbs
+++ b/app/assets/javascripts/admin/templates/logs/screened-ip-addresses.hbs
@@ -78,11 +78,10 @@
{{#unless item.editing}}
{{d-button
- class="btn-default"
+ class="btn-default btn-danger"
action=(action "destroy")
actionParam=item
- icon="far-trash-alt"
- class="btn-danger"}}
+ icon="far-trash-alt"}}
{{d-button
class="btn-default"
action=(action "edit")
diff --git a/app/assets/javascripts/discourse/controllers/history.js.es6 b/app/assets/javascripts/discourse/controllers/history.js.es6
index b42a99f1dd..369b37bbd4 100644
--- a/app/assets/javascripts/discourse/controllers/history.js.es6
+++ b/app/assets/javascripts/discourse/controllers/history.js.es6
@@ -199,17 +199,17 @@ export default Ember.Controller.extend(ModalFunctionality, {
@computed("displayingInline")
inlineClass(displayingInline) {
- return displayingInline ? "btn-primary" : "";
+ return displayingInline ? "btn-danger" : "btn-flat";
},
@computed("displayingSideBySide")
sideBySideClass(displayingSideBySide) {
- return displayingSideBySide ? "btn-primary" : "";
+ return displayingSideBySide ? "btn-danger" : "btn-flat";
},
@computed("displayingSideBySideMarkdown")
sideBySideMarkdownClass(displayingSideBySideMarkdown) {
- return displayingSideBySideMarkdown ? "btn-primary" : "";
+ return displayingSideBySideMarkdown ? "btn-danger" : "btn-flat";
},
@computed("model.category_id_changes")
diff --git a/app/assets/javascripts/discourse/controllers/move-to-topic.js.es6 b/app/assets/javascripts/discourse/controllers/move-to-topic.js.es6
index 6df047caa5..5e47258f7c 100644
--- a/app/assets/javascripts/discourse/controllers/move-to-topic.js.es6
+++ b/app/assets/javascripts/discourse/controllers/move-to-topic.js.es6
@@ -71,6 +71,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
this.set("selection", canSplitTopic ? "new_message" : "existing_message");
} else if (!canSplitTopic) {
this.set("selection", "existing_topic");
+ Ember.run.next(() => $("#choose-topic-title").focus());
}
},
diff --git a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 b/app/assets/javascripts/discourse/lib/plugin-api.js.es6
index 34a607d93e..a44548c175 100644
--- a/app/assets/javascripts/discourse/lib/plugin-api.js.es6
+++ b/app/assets/javascripts/discourse/lib/plugin-api.js.es6
@@ -55,7 +55,19 @@ class PluginApi {
* If the user is not logged in, it will be `null`.
**/
getCurrentUser() {
- return this.container.lookup("current-user:main");
+ return this._lookupContainer("current-user:main");
+ }
+
+ _lookupContainer(path) {
+ if (
+ !this.container ||
+ this.container.isDestroying ||
+ this.container.isDestroyed
+ ) {
+ return;
+ }
+
+ return this.container.lookup(path);
}
_resolveClass(resolverName, opts) {
@@ -222,7 +234,7 @@ class PluginApi {
* ```
**/
addPosterIcon(cb) {
- const site = this.container.lookup("site:main");
+ const site = this._lookupContainer("site:main");
const loc = site && site.mobileView ? "before" : "after";
decorateWidget(`poster-name:${loc}`, dec => {
@@ -424,8 +436,8 @@ class PluginApi {
```
**/
onAppEvent(name, fn) {
- let appEvents = this.container.lookup("app-events:main");
- appEvents.on(name, fn);
+ const appEvents = this._lookupContainer("app-events:main");
+ appEvents && appEvents.on(name, fn);
}
/**
@@ -562,7 +574,8 @@ class PluginApi {
* will issue a request to `/mice.json`
**/
addStorePluralization(thing, plural) {
- this.container.lookup("service:store").addPluralization(thing, plural);
+ const store = this._lookupContainer("service:store");
+ store && store.addPluralization(thing, plural);
}
/**
diff --git a/app/assets/javascripts/discourse/lib/search.js.es6 b/app/assets/javascripts/discourse/lib/search.js.es6
index 8fab105cfe..a3f47f7a12 100644
--- a/app/assets/javascripts/discourse/lib/search.js.es6
+++ b/app/assets/javascripts/discourse/lib/search.js.es6
@@ -80,7 +80,7 @@ export function translateResults(results, opts) {
more: groupedSearchResult[`more_${name}`]
};
- if (result.more && name === "posts" && opts.fullSearchUrl) {
+ if (result.more && componentName === "topic" && opts.fullSearchUrl) {
result.more = false;
result.moreUrl = opts.fullSearchUrl;
}
diff --git a/app/assets/javascripts/discourse/models/result-set.js.es6 b/app/assets/javascripts/discourse/models/result-set.js.es6
index 527477957a..5f85ce9417 100644
--- a/app/assets/javascripts/discourse/models/result-set.js.es6
+++ b/app/assets/javascripts/discourse/models/result-set.js.es6
@@ -25,12 +25,9 @@ export default Ember.ArrayProxy.extend({
if (this.get("length") < totalRows && !this.get("loadingMore")) {
this.set("loadingMore", true);
- const self = this;
return this.store
.appendResults(this, this.get("__type"), loadMoreUrl)
- .finally(function() {
- self.set("loadingMore", false);
- });
+ .finally(() => this.set("loadingMore", false));
}
return Ember.RSVP.resolve();
@@ -46,12 +43,9 @@ export default Ember.ArrayProxy.extend({
return;
}
- const self = this;
this.set("refreshing", true);
return this.store
.refreshResults(this, this.get("__type"), refreshUrl)
- .finally(function() {
- self.set("refreshing", false);
- });
+ .finally(() => this.set("refreshing", false));
}
});
diff --git a/app/assets/javascripts/discourse/models/store.js.es6 b/app/assets/javascripts/discourse/models/store.js.es6
index d1af36337e..f5b97f3856 100644
--- a/app/assets/javascripts/discourse/models/store.js.es6
+++ b/app/assets/javascripts/discourse/models/store.js.es6
@@ -83,12 +83,9 @@ export default Ember.Object.extend({
// Mostly for legacy, things like TopicList without ResultSets
findFiltered(type, findArgs) {
- const self = this;
return this.adapterFor(type)
.find(this, type, findArgs)
- .then(function(result) {
- return self._build(type, result);
- });
+ .then(result => this._build(type, result));
},
_hydrateFindResults(result, type, findArgs) {
@@ -149,28 +146,25 @@ export default Ember.Object.extend({
},
refreshResults(resultSet, type, url) {
- const self = this;
return ajax(url).then(result => {
- const typeName = Ember.String.underscore(self.pluralize(type));
+ const typeName = Ember.String.underscore(this.pluralize(type));
const content = result[typeName].map(obj =>
- self._hydrate(type, obj, result)
+ this._hydrate(type, obj, result)
);
resultSet.set("content", content);
});
},
appendResults(resultSet, type, url) {
- const self = this;
-
- return ajax(url).then(function(result) {
- let typeName = Ember.String.underscore(self.pluralize(type));
+ return ajax(url).then(result => {
+ let typeName = Ember.String.underscore(this.pluralize(type));
let pageTarget = result.meta || result;
let totalRows =
pageTarget["total_rows_" + typeName] || resultSet.get("totalRows");
let loadMoreUrl = pageTarget["load_more_" + typeName];
let content = result[typeName].map(obj =>
- self._hydrate(type, obj, result)
+ this._hydrate(type, obj, result)
);
resultSet.setProperties({ totalRows, loadMoreUrl });
@@ -300,20 +294,19 @@ export default Ember.Object.extend({
},
_hydrateEmbedded(type, obj, root) {
- const self = this;
- Object.keys(obj).forEach(function(k) {
+ Object.keys(obj).forEach(k => {
const m = /(.+)\_id(s?)$/.exec(k);
if (m) {
const subType = m[1];
if (m[2]) {
- const hydrated = obj[k].map(function(id) {
- return self._lookupSubType(subType, type, id, root);
- });
- obj[self.pluralize(subType)] = hydrated || [];
+ const hydrated = obj[k].map(id =>
+ this._lookupSubType(subType, type, id, root)
+ );
+ obj[this.pluralize(subType)] = hydrated || [];
delete obj[k];
} else {
- const hydrated = self._lookupSubType(subType, type, obj[k], root);
+ const hydrated = this._lookupSubType(subType, type, obj[k], root);
if (hydrated) {
obj[subType] = hydrated;
delete obj[k];
diff --git a/app/assets/javascripts/discourse/models/topic.js.es6 b/app/assets/javascripts/discourse/models/topic.js.es6
index af6cc421bf..489333e588 100644
--- a/app/assets/javascripts/discourse/models/topic.js.es6
+++ b/app/assets/javascripts/discourse/models/topic.js.es6
@@ -78,7 +78,7 @@ const Topic = RestModel.extend({
}
}
- const poster_ids = _.pluck(posters, "user_id");
+ const poster_ids = posters.map(p => p.user && p.user.id).filter(id => id);
participants.some(p => {
if (!poster_ids.includes(p.user_id)) {
users.splice(users.length - pushOffset, 0, p);
diff --git a/app/assets/javascripts/discourse/templates/components/d-editor.hbs b/app/assets/javascripts/discourse/templates/components/d-editor.hbs
index 4391669a79..41694e0b9d 100644
--- a/app/assets/javascripts/discourse/templates/components/d-editor.hbs
+++ b/app/assets/javascripts/discourse/templates/components/d-editor.hbs
@@ -39,7 +39,7 @@
{{conditional-loading-spinner condition=loading}}
- {{textarea tabindex=tabindex value=value class="d-editor-input" placeholder=placeholderTranslated disabled=disabled}}
+ {{textarea autocomplete="off" tabindex=tabindex value=value class="d-editor-input" placeholder=placeholderTranslated disabled=disabled}}
{{popup-input-tip validation=validation}}
{{plugin-outlet name="after-d-editor" tagName="" args=outletArgs}}
diff --git a/app/assets/javascripts/discourse/templates/components/user-card-contents.hbs b/app/assets/javascripts/discourse/templates/components/user-card-contents.hbs
index 33da28314e..a7fc8cac35 100644
--- a/app/assets/javascripts/discourse/templates/components/user-card-contents.hbs
+++ b/app/assets/javascripts/discourse/templates/components/user-card-contents.hbs
@@ -17,7 +17,7 @@
- {{plugin-outlet name="user-card-after-username" args=(hash user=user) tagName=''}}
+ {{plugin-outlet name="user-card-after-username" args=(hash user=user showUser=(action "showUser")) tagName=''}}
{{#unless nameFirst}}
{{#if user.name}}
diff --git a/app/assets/javascripts/discourse/templates/composer.hbs b/app/assets/javascripts/discourse/templates/composer.hbs
index c59c4b5760..4f313982e7 100644
--- a/app/assets/javascripts/discourse/templates/composer.hbs
+++ b/app/assets/javascripts/discourse/templates/composer.hbs
@@ -106,8 +106,8 @@
uploadIcon=uploadIcon
isCancellable=isCancellable
uploadProgress=uploadProgress
- groupsMentioned="groupsMentioned"
- cannotSeeMention="cannotSeeMention"
+ groupsMentioned=(action "groupsMentioned")
+ cannotSeeMention=(action "cannotSeeMention")
importQuote=(action "importQuote")
togglePreview=(action "togglePreview")
showToolbar=showToolbar
diff --git a/app/assets/javascripts/discourse/templates/mobile/list/topic-list-item.raw.hbs b/app/assets/javascripts/discourse/templates/mobile/list/topic-list-item.raw.hbs
index 2363ec4371..7333de7d55 100644
--- a/app/assets/javascripts/discourse/templates/mobile/list/topic-list-item.raw.hbs
+++ b/app/assets/javascripts/discourse/templates/mobile/list/topic-list-item.raw.hbs
@@ -8,6 +8,7 @@
{{/unless~}}
+ {{~raw-plugin-outlet name="topic-list-before-status"}}
{{~raw "topic-status" topic=topic~}}
{{~topic-link topic~}}
{{~#if topic.featured_link~}}
diff --git a/app/assets/stylesheets/common/admin/customize.scss b/app/assets/stylesheets/common/admin/customize.scss
index a552dd0293..e6654ac80e 100644
--- a/app/assets/stylesheets/common/admin/customize.scss
+++ b/app/assets/stylesheets/common/admin/customize.scss
@@ -137,6 +137,10 @@
display: inline-block;
vertical-align: top;
+ .btn {
+ line-height: $line-height-medium; // Temporary button-height fix
+ }
+
.title {
font-size: $font-up-4;
font-weight: bold;
@@ -208,7 +212,6 @@
}
}
.external-link {
- display: inline-block;
display: block;
margin-bottom: 5px;
}
diff --git a/app/assets/stylesheets/common/base/compose.scss b/app/assets/stylesheets/common/base/compose.scss
index b00124a639..f57cac9d6e 100644
--- a/app/assets/stylesheets/common/base/compose.scss
+++ b/app/assets/stylesheets/common/base/compose.scss
@@ -98,7 +98,7 @@
display: flex;
align-items: center;
.d-icon {
- color: $primary-high;
+ color: $primary-medium;
}
.reply-details {
max-width: calc(100% - 175px);
diff --git a/app/assets/stylesheets/common/base/discourse.scss b/app/assets/stylesheets/common/base/discourse.scss
index 24a7bc1661..be05dfd9a8 100644
--- a/app/assets/stylesheets/common/base/discourse.scss
+++ b/app/assets/stylesheets/common/base/discourse.scss
@@ -73,7 +73,9 @@ button {
&.ok {
background: $success;
color: $secondary;
-
+ .d-icon {
+ color: currentColor;
+ }
@include hover {
background: lighten($success, 10%);
color: $secondary;
@@ -83,7 +85,9 @@ button {
&.cancel {
background: $danger;
color: $secondary;
-
+ .d-icon {
+ color: currentColor;
+ }
@include hover {
background: lighten($danger, 10%);
color: $secondary;
diff --git a/app/assets/stylesheets/common/base/header.scss b/app/assets/stylesheets/common/base/header.scss
index 14828be01e..b31d29a4a3 100644
--- a/app/assets/stylesheets/common/base/header.scss
+++ b/app/assets/stylesheets/common/base/header.scss
@@ -100,10 +100,6 @@
width: 2.2857em;
height: 2.2857em;
padding: 0.2143em;
- color: dark-light-choose(
- scale-color($header_primary, $lightness: 50%),
- $header_primary
- );
text-decoration: none;
cursor: pointer;
border-top: 1px solid transparent;
@@ -117,7 +113,6 @@
}
&:hover,
&:focus {
- color: $primary;
background-color: $primary-low;
border-top: 1px solid transparent;
border-left: 1px solid transparent;
@@ -131,13 +126,14 @@
.drop-down-mode & {
.active .icon {
position: relative;
- color: #7b7b7b;
background-color: $secondary;
cursor: default;
border-top: 1px solid $primary-low;
border-left: 1px solid $primary-low;
border-right: 1px solid $primary-low;
-
+ .d-icon {
+ color: $primary-medium;
+ }
&:after {
display: block;
position: absolute;
@@ -160,6 +156,7 @@
font-size: $font-up-4;
line-height: $line-height-large;
display: inline-block;
+ color: $header_primary-low-mid;
}
.notifications {
position: relative;
diff --git a/app/assets/stylesheets/common/base/menu-panel.scss b/app/assets/stylesheets/common/base/menu-panel.scss
index b2eb86b284..41cc397501 100644
--- a/app/assets/stylesheets/common/base/menu-panel.scss
+++ b/app/assets/stylesheets/common/base/menu-panel.scss
@@ -153,11 +153,12 @@
margin: 0.5em 0;
}
- .fa {
- color: dark-light-choose($primary-medium, $secondary-medium);
+ .d-icon,
+ &:hover .d-icon {
+ color: $primary-medium;
}
.icon {
- color: dark-light-choose($primary-high, $secondary-low);
+ color: $primary-high;
}
li {
background-color: $tertiary-low;
diff --git a/app/assets/stylesheets/common/base/modal.scss b/app/assets/stylesheets/common/base/modal.scss
index 391f724a48..848b5cd4d0 100644
--- a/app/assets/stylesheets/common/base/modal.scss
+++ b/app/assets/stylesheets/common/base/modal.scss
@@ -318,6 +318,9 @@
.d-modal-cancel {
margin-left: 1em;
color: $primary-medium;
+ &:hover {
+ color: $danger;
+ }
}
.delete-user-modal {
diff --git a/app/assets/stylesheets/common/base/user-badges.scss b/app/assets/stylesheets/common/base/user-badges.scss
index 79033dda03..304274f055 100644
--- a/app/assets/stylesheets/common/base/user-badges.scss
+++ b/app/assets/stylesheets/common/base/user-badges.scss
@@ -328,7 +328,7 @@
.check-display {
display: inline-block;
- width: 18px;
+ padding: 0 0.25em;
border-radius: 10px;
text-align: center;
.fa {
diff --git a/app/assets/stylesheets/common/components/buttons.scss b/app/assets/stylesheets/common/components/buttons.scss
index f9cf292688..6b45685f60 100644
--- a/app/assets/stylesheets/common/components/buttons.scss
+++ b/app/assets/stylesheets/common/components/buttons.scss
@@ -17,7 +17,9 @@
transition: all 0.25s;
box-sizing: border-box;
min-height: 30px;
-
+ .d-icon {
+ transition: color 0.25s;
+ }
&:active,
&.btn-active {
text-shadow: none;
@@ -49,6 +51,9 @@
color: $primary;
font-weight: normal;
background: $primary-low;
+ .d-icon {
+ color: $primary-high;
+ }
&[href] {
color: $primary;
@@ -60,24 +65,29 @@
&.btn-hover {
background: $primary-medium;
color: $secondary;
+ .d-icon {
+ color: $secondary-very-high;
+ }
}
}
&[disabled],
&.disabled {
background: $primary-low;
+ .d-icon {
+ color: $primary-medium;
+ }
&:hover {
color: dark-light-choose($primary-low-mid, $secondary-high);
+ .d-icon {
+ color: $primary-low-mid;
+ }
}
cursor: not-allowed;
}
.d-icon {
- opacity: 0.7;
line-height: $line-height-medium; // Match button text line-height
}
- &.btn-primary .d-icon {
- opacity: 1;
- }
}
// Primary button
@@ -88,7 +98,9 @@
font-weight: normal;
color: $secondary;
background: $tertiary;
-
+ .d-icon {
+ color: currentColor;
+ }
&[href] {
color: $secondary;
}
@@ -100,6 +112,9 @@
scale-color($tertiary, $lightness: -20%),
scale-color($tertiary, $lightness: 20%)
);
+ .d-icon {
+ color: currentColor;
+ }
}
}
&:active,
@@ -112,6 +127,9 @@
&[disabled],
&.disabled {
background: $tertiary;
+ .d-icon {
+ color: currentColor;
+ }
}
}
@@ -122,6 +140,9 @@
color: $secondary;
font-weight: normal;
background: $danger;
+ .d-icon {
+ color: $danger-low;
+ }
&[href] {
color: $secondary;
}
@@ -133,6 +154,9 @@
scale-color($danger, $lightness: -20%),
scale-color($danger, $lightness: 20%)
);
+ .d-icon {
+ color: $danger-low;
+ }
}
}
&:active,
@@ -142,6 +166,9 @@
&[disabled],
&.disabled {
background: $danger;
+ .d-icon {
+ color: $danger-low;
+ }
}
}
@@ -214,7 +241,15 @@
border: 0;
outline: 0;
line-height: $line-height-small;
+ transition: color 0.25s, background 0.25s;
.d-icon {
- opacity: 0.7;
+ color: $primary-low-mid;
+ }
+ .discourse-no-touch & {
+ &:hover {
+ .d-icon {
+ color: $primary;
+ }
+ }
}
}
diff --git a/app/assets/stylesheets/common/d-editor.scss b/app/assets/stylesheets/common/d-editor.scss
index 8d8307d882..5b402bfa80 100644
--- a/app/assets/stylesheets/common/d-editor.scss
+++ b/app/assets/stylesheets/common/d-editor.scss
@@ -82,9 +82,11 @@
.btn,
.btn-default {
background-color: transparent;
- color: $primary-high;
padding: 4px 8px;
display: inline-block;
+ .d-icon {
+ color: $primary-medium;
+ }
@media all and (max-width: 800px) {
padding: 5px;
}
diff --git a/app/assets/stylesheets/common/foundation/variables.scss b/app/assets/stylesheets/common/foundation/variables.scss
index 2e56e48654..1bbd8c1aa2 100644
--- a/app/assets/stylesheets/common/foundation/variables.scss
+++ b/app/assets/stylesheets/common/foundation/variables.scss
@@ -203,9 +203,12 @@ $primary-low: dark-light-diff($primary, $secondary, 90%, -78%);
$primary-low-mid: dark-light-diff($primary, $secondary, 70%, -45%);
$primary-medium: dark-light-diff($primary, $secondary, 50%, -35%);
$primary-high: dark-light-diff($primary, $secondary, 30%, -25%);
+$primary-very-high: dark-light-diff($primary, $secondary, 15%, -10%);
//header_primary
$header_primary-low: dark-light-diff($header_primary, $secondary, 90%, -78%);
+$header_primary-low-mid: dark-light-diff($primary, $secondary, 70%, -45%);
+
$header_primary-medium: dark-light-diff($header_primary, $secondary, 50%, -35%);
$header_primary-high: dark-light-diff(
$header_primary,
@@ -213,11 +216,18 @@ $header_primary-high: dark-light-diff(
30%,
-25%
);
+$header_primary-very-high: dark-light-diff(
+ $header_primary,
+ $header_background,
+ 15%,
+ -10%
+);
//secondary
$secondary-low: dark-light-diff($secondary, $primary, 70%, -70%);
$secondary-medium: dark-light-diff($secondary, $primary, 50%, -50%);
$secondary-high: dark-light-diff($secondary, $primary, 30%, -35%);
+$secondary-very-high: dark-light-diff($secondary, $primary, 7%, -7%);
//tertiary
$tertiary-low: dark-light-diff($tertiary, $secondary, 85%, -65%);
diff --git a/app/assets/stylesheets/common/select-kit/select-kit.scss b/app/assets/stylesheets/common/select-kit/select-kit.scss
index 874dd6dd7c..87497e62c8 100644
--- a/app/assets/stylesheets/common/select-kit/select-kit.scss
+++ b/app/assets/stylesheets/common/select-kit/select-kit.scss
@@ -55,7 +55,7 @@
}
.d-icon {
- opacity: 0.7;
+ color: $primary-high;
}
.select-kit-header {
diff --git a/app/assets/stylesheets/desktop/history.scss b/app/assets/stylesheets/desktop/history.scss
index 9f08fadb88..afb62814f6 100644
--- a/app/assets/stylesheets/desktop/history.scss
+++ b/app/assets/stylesheets/desktop/history.scss
@@ -20,15 +20,6 @@
text-align: right;
display: inline-block;
float: right;
-
- .btn {
- background-color: inherit;
- color: blend-primary-secondary(50%);
- }
- .btn-primary {
- color: $primary;
- font-weight: bold;
- }
}
#revisions {
diff --git a/app/assets/stylesheets/desktop/topic-post.scss b/app/assets/stylesheets/desktop/topic-post.scss
index a605c4db5f..a6d836b956 100644
--- a/app/assets/stylesheets/desktop/topic-post.scss
+++ b/app/assets/stylesheets/desktop/topic-post.scss
@@ -23,7 +23,7 @@
.actions .fade-out {
.discourse-no-touch & {
opacity: 0.7;
- transition: opacity 0.7s ease-in-out;
+ transition: background 0.25s, opacity 0.7s ease-in-out;
}
.discourse-touch & {
opacity: 1;
@@ -65,6 +65,9 @@ nav.post-controls {
.d-hover {
background: none;
}
+ .d-icon {
+ color: $love;
+ }
}
&:active {
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4);
@@ -146,6 +149,9 @@ nav.post-controls {
margin-right: 0;
color: dark-light-choose($primary-high, $secondary-low);
margin-left: 10px;
+ .d-icon {
+ color: dark-light-choose($primary-high, $secondary-low);
+ }
}
.create .d-icon {
margin-right: 5px;
@@ -172,16 +178,23 @@ nav.post-controls {
position: relative;
}
&.delete.d-hover,
+ &.delete:hover,
&.delete:focus {
background: $danger;
color: $secondary;
+ .d-icon {
+ color: $secondary;
+ }
}
&.like.d-hover,
&.like:focus {
color: $love;
background: $love-low;
+ .d-icon {
+ color: $love;
+ }
}
- &.has-like {
+ &.has-like .d-icon {
color: $love;
}
&.has-like[disabled]:hover {
@@ -192,7 +205,7 @@ nav.post-controls {
}
&.bookmark {
padding: 8px 11px;
- &.bookmarked {
+ &.bookmarked .d-icon {
color: $tertiary;
}
}
@@ -364,7 +377,8 @@ nav.post-controls {
font-size: $font-up-2;
line-height: $line-height-medium;
}
- button .d-icon {
+ button .d-icon,
+ button:hover .d-icon {
color: $primary-high;
}
.avatar a {
diff --git a/app/assets/stylesheets/mobile/topic-post.scss b/app/assets/stylesheets/mobile/topic-post.scss
index cc062ce6d9..811eabbc0c 100644
--- a/app/assets/stylesheets/mobile/topic-post.scss
+++ b/app/assets/stylesheets/mobile/topic-post.scss
@@ -83,14 +83,20 @@ span.badge-posts {
margin: 10px 0 10px 0;
}
&.reply {
- color: $primary-high;
+ .d-icon {
+ color: $primary-high;
+ }
margin-left: auto;
}
&.has-like {
- color: $love;
+ .d-icon {
+ color: $love;
+ }
}
&.bookmarked {
- color: $tertiary;
+ .d-icon {
+ color: $tertiary;
+ }
}
}
}
diff --git a/app/assets/stylesheets/vendor/normalize.scss b/app/assets/stylesheets/vendor/normalize.scss
index b694193cd7..ad7de2bd8a 100644
--- a/app/assets/stylesheets/vendor/normalize.scss
+++ b/app/assets/stylesheets/vendor/normalize.scss
@@ -184,14 +184,6 @@ img {
border: 0;
}
-/**
- * Correct overflow not hidden in IE 9/10/11.
- */
-
-svg:not(:root) {
- overflow: hidden;
-}
-
/* Grouping content
========================================================================== */
diff --git a/app/controllers/admin/email_controller.rb b/app/controllers/admin/email_controller.rb
index 2415546005..148b364dc0 100644
--- a/app/controllers/admin/email_controller.rb
+++ b/app/controllers/admin/email_controller.rb
@@ -89,6 +89,8 @@ class Admin::EmailController < Admin::AdminController
params.require(:last_seen_at)
params.require(:username)
user = User.find_by_username(params[:username])
+ raise Discourse::InvalidParameters unless user
+
renderer = Email::Renderer.new(UserNotifications.digest(user, since: params[:last_seen_at]))
render json: MultiJson.dump(html_content: renderer.html, text_content: renderer.text)
end
diff --git a/app/controllers/admin/themes_controller.rb b/app/controllers/admin/themes_controller.rb
index 15027da7ff..f927eee337 100644
--- a/app/controllers/admin/themes_controller.rb
+++ b/app/controllers/admin/themes_controller.rb
@@ -84,11 +84,13 @@ class Admin::ThemesController < Admin::AdminController
rescue RemoteTheme::ImportError => e
render_json_error e.message
end
- elsif params[:bundle] || params[:theme] && ["application/x-gzip", "application/gzip"].include?(params[:theme].content_type)
+ elsif params[:bundle] || (params[:theme] && ["application/x-gzip", "application/gzip"].include?(params[:theme].content_type))
# params[:bundle] used by theme CLI. params[:theme] used by admin UI
bundle = params[:bundle] || params[:theme]
+ theme_id = params[:theme_id]
+ match_theme_by_name = !!params[:bundle] && !params.key?(:theme_id) # Old theme CLI behavior, match by name. Remove Jan 2020
begin
- @theme = RemoteTheme.update_tgz_theme(bundle.path, match_theme: !!params[:bundle], user: current_user)
+ @theme = RemoteTheme.update_tgz_theme(bundle.path, match_theme: match_theme_by_name, user: current_user, theme_id: theme_id)
log_theme_change(nil, @theme)
render json: @theme, status: :created
rescue RemoteTheme::ImportError => e
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index 64d08d4e1a..481d5d9c29 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -75,7 +75,11 @@ class UploadsController < ApplicationController
}
opts[:disposition] = "inline" if params[:inline]
opts[:disposition] ||= "attachment" unless FileHelper.is_supported_image?(upload.original_filename)
- send_file(Discourse.store.path_for(upload), opts)
+
+ file_path = Discourse.store.path_for(upload)
+ return render_404 unless file_path
+
+ send_file(file_path, opts)
else
render_404
end
diff --git a/app/controllers/webhooks_controller.rb b/app/controllers/webhooks_controller.rb
index 5480fe3368..b5f3fdd4f6 100644
--- a/app/controllers/webhooks_controller.rb
+++ b/app/controllers/webhooks_controller.rb
@@ -3,39 +3,9 @@ require "openssl"
class WebhooksController < ActionController::Base
def mailgun
- # can't verify data without an API key
return mailgun_failure if SiteSetting.mailgun_api_key.blank?
- # token is a random string of 50 characters
- token = params["token"]
- return mailgun_failure if token.blank? || token.size != 50
-
- # prevent replay attack
- key = "mailgun_token_#{token}"
- return mailgun_failure unless $redis.setnx(key, 1)
- $redis.expire(key, 10.minutes)
-
- # ensure timestamp isn't too far from current time
- timestamp = params["timestamp"]
- return mailgun_failure if (Time.at(timestamp.to_i) - Time.now).abs > 24.hours.to_i
-
- # check the signature
- return mailgun_failure unless mailgun_verify(timestamp, token, params["signature"])
-
- event = params["event"]
- message_id = params["Message-Id"].tr("<>", "")
- to_address = params["recipient"]
-
- # only handle soft bounces, because hard bounces are also handled
- # by the "dropped" event and we don't want to increase bounce score twice
- # for the same message
- if event == "bounced".freeze && params["error"]["4."]
- process_bounce(message_id, to_address, SiteSetting.soft_bounce_score)
- elsif event == "dropped".freeze
- process_bounce(message_id, to_address, SiteSetting.hard_bounce_score)
- end
-
- mailgun_success
+ params["event-data"] ? handle_mailgun_new(params) : handle_mailgun_legacy(params)
end
def sendgrid
@@ -127,10 +97,59 @@ class WebhooksController < ActionController::Base
render body: nil, status: 200
end
- def mailgun_verify(timestamp, token, signature)
- digest = OpenSSL::Digest::SHA256.new
- data = "#{timestamp}#{token}"
- signature == OpenSSL::HMAC.hexdigest(digest, SiteSetting.mailgun_api_key, data)
+ def valid_mailgun_signature?(token, timestamp, signature)
+ # token is a random 50 characters string
+ return false if token.blank? || token.size != 50
+
+ # prevent replay attacks
+ key = "mailgun_token_#{token}"
+ return false unless $redis.setnx(key, 1)
+ $redis.expire(key, 10.minutes)
+
+ # ensure timestamp isn't too far from current time
+ return false if (Time.at(timestamp.to_i) - Time.now).abs > 12.hours.to_i
+
+ # check the signature
+ signature == OpenSSL::HMAC.hexdigest("SHA256", SiteSetting.mailgun_api_key, "#{timestamp}#{token}")
+ end
+
+ def handle_mailgun_legacy(params)
+ return mailgun_failure unless valid_mailgun_signature?(params["token"], params["timestamp"], params["signature"])
+
+ event = params["event"]
+ message_id = params["Message-Id"].tr("<>", "")
+ to_address = params["recipient"]
+
+ # only handle soft bounces, because hard bounces are also handled
+ # by the "dropped" event and we don't want to increase bounce score twice
+ # for the same message
+ if event == "bounced".freeze && params["error"]["4."]
+ process_bounce(message_id, to_address, SiteSetting.soft_bounce_score)
+ elsif event == "dropped".freeze
+ process_bounce(message_id, to_address, SiteSetting.hard_bounce_score)
+ end
+
+ mailgun_success
+ end
+
+ def handle_mailgun_new(params)
+ signature = params["signature"]
+ return mailgun_failure unless valid_mailgun_signature?(signature["token"], signature["timestamp"], signature["signature"])
+
+ data = params["event-data"]
+ message_id = data.dig("message", "headers", "message-id")
+ to_address = data["recipient"]
+ severity = data["severity"]
+
+ if data["event"] == "failed".freeze
+ if severity == "temporary".freeze
+ process_bounce(message_id, to_address, SiteSetting.soft_bounce_score)
+ elsif severity == "permanent".freeze
+ process_bounce(message_id, to_address, SiteSetting.hard_bounce_score)
+ end
+ end
+
+ mailgun_success
end
def process_bounce(message_id, to_address, bounce_score)
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 8ca6e21fea..4963b95832 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -212,16 +212,18 @@ module ApplicationHelper
opts ||= {}
opts[:url] ||= "#{Discourse.base_url_no_prefix}#{request.fullpath}"
- twitter_summary_large_image_url =
- SiteSetting.site_twitter_summary_large_image_url
+ if opts[:image].blank?
+ twitter_summary_large_image_url = SiteSetting.site_twitter_summary_large_image_url
- opengraph_image_url = SiteSetting.opengraph_image_url
+ if twitter_summary_large_image_url.present?
+ opts[:twitter_summary_large_image] = twitter_summary_large_image_url
+ end
- if opts[:image].blank? && (opengraph_image_url.present? || twitter_summary_large_image_url.present?)
- opts[:twitter_summary_large_image] = twitter_summary_large_image_url if twitter_summary_large_image_url.present?
- opts[:image] = opengraph_image_url.present? ? opengraph_image_url : twitter_summary_large_image_url
- elsif opts[:image].blank? && SiteSetting.site_apple_touch_icon_url.present?
- opts[:image] = SiteSetting.site_apple_touch_icon_url
+ opts[:image] = SiteSetting.opengraph_image_url.presence ||
+ twitter_summary_large_image_url.presence ||
+ SiteSetting.site_large_icon_url.presence ||
+ SiteSetting.site_apple_touch_icon_url.presence ||
+ SiteSetting.site_logo_url.presence
end
# Use the correct scheme for opengraph/twitter image
@@ -478,6 +480,8 @@ module ApplicationHelper
absolute_url = "#{uri.scheme}:#{link}"
elsif link.start_with?("/uploads/")
absolute_url = "#{Discourse.base_url}#{link}"
+ elsif link.start_with?("/images/")
+ absolute_url = "#{Discourse.base_url}#{link}"
elsif GlobalSetting.relative_url_root && link.start_with?(GlobalSetting.relative_url_root)
absolute_url = "#{Discourse.base_url_no_prefix}#{link}"
end
diff --git a/app/models/remote_theme.rb b/app/models/remote_theme.rb
index 0e89c160da..363656c642 100644
--- a/app/models/remote_theme.rb
+++ b/app/models/remote_theme.rb
@@ -32,12 +32,13 @@ class RemoteTheme < ActiveRecord::Base
raise ImportError.new I18n.t("themes.import_error.about_json")
end
- def self.update_tgz_theme(filename, match_theme: false, user: Discourse.system_user)
+ def self.update_tgz_theme(filename, match_theme: false, user: Discourse.system_user, theme_id: nil)
importer = ThemeStore::TgzImporter.new(filename)
importer.import!
theme_info = RemoteTheme.extract_theme_info(importer)
- theme = Theme.find_by(name: theme_info["name"]) if match_theme
+ theme = Theme.find_by(name: theme_info["name"]) if match_theme # Old theme CLI method, remove Jan 2020
+ theme = Theme.find_by(id: theme_id) if theme_id # New theme CLI method
theme ||= Theme.new(user_id: user&.id || -1, name: theme_info["name"])
theme.component = theme_info["component"].to_s == "true"
@@ -176,6 +177,7 @@ class RemoteTheme < ActiveRecord::Base
def update_theme_color_schemes(theme, schemes)
missing_scheme_names = Hash[*theme.color_schemes.pluck(:name, :id).flatten]
+ ordered_schemes = []
schemes&.each do |name, colors|
missing_scheme_names.delete(name)
@@ -188,12 +190,14 @@ class RemoteTheme < ActiveRecord::Base
theme.notify_color_change(c)
end
end
+ ordered_schemes << existing
else
scheme = theme.color_schemes.build(name: name)
ColorScheme.base.colors_hashes.each do |color|
override = normalize_override(colors[color[:name]])
scheme.color_scheme_colors << ColorSchemeColor.new(name: color[:name], hex: override || color[:hex])
end
+ ordered_schemes << scheme
end
end
@@ -201,6 +205,10 @@ class RemoteTheme < ActiveRecord::Base
ColorScheme.where(id: missing_scheme_names.values).delete_all
# we may have stuff pointed at the incorrect scheme?
end
+
+ if theme.new_record?
+ theme.color_scheme = ordered_schemes.first
+ end
end
def github_diff_link
@@ -228,17 +236,21 @@ end
#
# Table name: remote_themes
#
-# id :integer not null, primary key
-# remote_url :string not null
-# remote_version :string
-# local_version :string
-# about_url :string
-# license_url :string
-# commits_behind :integer
-# remote_updated_at :datetime
-# created_at :datetime not null
-# updated_at :datetime not null
-# private_key :text
-# branch :string
-# last_error_text :text
+# id :integer not null, primary key
+# remote_url :string not null
+# remote_version :string
+# local_version :string
+# about_url :string
+# license_url :string
+# commits_behind :integer
+# remote_updated_at :datetime
+# created_at :datetime not null
+# updated_at :datetime not null
+# private_key :text
+# branch :string
+# last_error_text :text
+# authors :string
+# theme_version :string
+# minimum_discourse_version :string
+# maximum_discourse_version :string
#
diff --git a/app/models/single_sign_on_record.rb b/app/models/single_sign_on_record.rb
index 1ceeacf5d6..417a5f3590 100644
--- a/app/models/single_sign_on_record.rb
+++ b/app/models/single_sign_on_record.rb
@@ -24,4 +24,5 @@ end
# Indexes
#
# index_single_sign_on_records_on_external_id (external_id) UNIQUE
+# index_single_sign_on_records_on_user_id (user_id)
#
diff --git a/app/models/user_option.rb b/app/models/user_option.rb
index e51f10b3fe..aa86004975 100644
--- a/app/models/user_option.rb
+++ b/app/models/user_option.rb
@@ -202,6 +202,7 @@ end
# theme_ids :integer default([]), not null, is an Array
# hide_profile_and_presence :boolean default(FALSE), not null
# text_size_key :integer default(0), not null
+# text_size_seq :integer default(0), not null
#
# Indexes
#
diff --git a/app/services/user_anonymizer.rb b/app/services/user_anonymizer.rb
index d87c7e6da7..ae480252b5 100644
--- a/app/services/user_anonymizer.rb
+++ b/app/services/user_anonymizer.rb
@@ -26,7 +26,6 @@ class UserAnonymizer
@user.reload
@user.password = SecureRandom.hex
- @user.email = "#{@user.username}@anonymized.invalid"
@user.name = SiteSetting.full_name_required ? @user.username : nil
@user.date_of_birth = nil
@user.title = nil
@@ -37,7 +36,8 @@ class UserAnonymizer
@user.registration_ip_address = @opts[:anonymize_ip]
end
- @user.save
+ @user.save!
+ @user.primary_email.update_attribute(:email, "#{@user.username}@anonymized.invalid")
options = @user.user_option
options.email_always = false
@@ -45,7 +45,7 @@ class UserAnonymizer
options.email_digests = false
options.email_private_messages = false
options.email_direct = false
- options.save
+ options.save!
if profile = @user.user_profile
profile.update(location: nil, website: nil, bio_raw: nil, bio_cooked: nil,
@@ -61,6 +61,7 @@ class UserAnonymizer
@user.instagram_user_info.try(:destroy)
@user.user_open_ids.find_each { |x| x.destroy }
@user.api_key.try(:destroy)
+ @user.user_emails.secondary.destroy_all
@user_history = log_action
end
@@ -101,6 +102,6 @@ class UserAnonymizer
history_details[:details] = "username: #{@prev_username}"
end
- UserHistory.create(history_details)
+ UserHistory.create!(history_details)
end
end
diff --git a/app/views/topics/show.html.erb b/app/views/topics/show.html.erb
index 138646bd43..456135d668 100644
--- a/app/views/topics/show.html.erb
+++ b/app/views/topics/show.html.erb
@@ -47,10 +47,16 @@
<%= u.username %>
- <%= "(#{u.name})" if (SiteSetting.display_name_on_posts && SiteSetting.enable_names? && !u.name.blank?) %>
-
- <%= post.created_at %>
-
+ <%= "(#{u.name})" if (SiteSetting.display_name_on_posts && SiteSetting.enable_names? && !u.name.blank?) %>
+ <%
+ who_username = post.custom_fields["action_code_who"] || ""
+ if post.action_code
+ %>
+ <%= t("js.action_codes.#{post.action_code}", when: "", who: who_username).html_safe %>
+ <% end %>
+
+ <%= post.created_at %>
+
#<%= post.post_number %>
diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml
index 1e40693b44..51ef58d9a4 100644
--- a/config/locales/client.de.yml
+++ b/config/locales/client.de.yml
@@ -597,6 +597,8 @@ de:
first_notification: "Deine erste Benachrichtigung! Wähle sie aus um fortzufahren."
disable_jump_reply: "Springe nicht zu meinem Beitrag, nachdem ich geantwortet habe"
dynamic_favicon: "Zeige die Anzahl der neuen und geänderten Themen im Browser-Symbol an"
+ theme_default_on_all_devices: "Mache dieses Theme zum Standard für alle meine Geräte"
+ text_size_default_on_all_devices: "Mache diese Schriftgröße zum Standard für alle meine Geräte"
allow_private_messages: "Anderen Benutzern erlauben, mir persönliche Nachrichten zu schicken"
external_links_in_new_tab: "Öffne alle externen Links in einem neuen Tab"
enable_quoting: "Aktiviere Zitatantwort mit dem hervorgehobenen Text"
@@ -2635,6 +2637,7 @@ de:
version_check_pending: "Sieht so aus, als hättest du vor Kurzem aktualisiert. Großartig!"
installed_version: "Installiert"
latest_version: "Neueste"
+ problems_found: "Ein paar Ratschläge basierend auf deinen aktuellen Website-Einstellungen"
last_checked: "Zuletzt geprüft"
refresh_problems: "Aktualisieren"
no_problems: "Es wurden keine Probleme gefunden."
@@ -3093,6 +3096,7 @@ de:
convert_theme_alert: "Bist Du sicher, dass du dieses Theme in eine Komponente umwandeln möchtest? Sie wird als übergeordnetes Element entfernt von %{relatives}."
convert_theme_tooltip: "Wandle dieses Theme in eine Komponente um"
inactive_themes: "Inaktive Themes:"
+ inactive_components: "Nicht verwendete Komponenten:"
broken_theme_tooltip: "Dieses Theme hat fehlerhaftes CSS, HTML oder YAML."
default_theme_tooltip: "Dieses Theme ist das Standardtheme der Seite."
updates_available_tooltip: "Updates sind verfügbar für dieses Theme"
@@ -3118,10 +3122,19 @@ de:
edit_css_html_help: "Du hast kein CSS oder HTML bearbeitet"
delete_upload_confirm: "Upload löschen? (Theme-CSS funktioniert eventuell nicht mehr!)"
import_web_tip: "Repository mit dem Theme"
+ import_file_tip: ".tar.gz oder .dcstyle.json Datei mit dem Theme"
is_private: "Theme ist in einem privaten Git-Repository"
remote_branch: "Branch-Name (optional)"
public_key: "Gewähre dem folgenden öffentlichen Schlüssel den Zugriff auf das Repository:"
+ about_theme: "Über uns"
license: "Lizenz"
+ version: "Version:"
+ authors: "Erstellt von:"
+ source_url: "Quelle"
+ required_version:
+ error: "Dieses Theme wurde automatisch deaktiviert, weil es mit dieser Discourse-Version nicht kompatibel ist."
+ minimum: "Erfordert Discourse-Version {{version}} oder höher"
+ maximum: "Erfordert Discourse-Version {{version}} oder niedriger."
component_of: "Komponente von:"
update_to_latest: "Aktualisieren auf neueste Version"
check_for_updates: "Nach Aktualisierungen suchen"
@@ -3137,6 +3150,7 @@ de:
other: "Theme liegt {{count}} Commits zurück!"
compare_commits: "(Siehe neue Beiträge)"
repo_unreachable: "Das Git-Repository dieses Themes konnte nicht kontaktiert werden. Fehlermeldung:"
+ imported_from_archive: "Dieses Theme wurde aus einer .tar.gz-Datei importiert."
scss:
text: "CSS"
title: "Gib benutzerdefiniertes CSS ein, wir akzeptieren alle gültigen CSS und SCSS-Stile"
@@ -3834,6 +3848,10 @@ de:
with_post: "
%{username} für Beitrag in %{link}"
with_post_time: "
%{username} für Beitrag in %{link} um
%{time} "
with_time: "
%{username} um
%{time} "
+ badge_intro:
+ title: 'Wähle ein bestehendes Abzeichen oder erstelle ein neues, um loszulegen'
+ what_are_badges_title: 'Was sind Abzeichen?'
+ badge_query_examples_title: 'Beispiele für Abzeichen-Abfragen'
emoji:
title: "Emoji"
help: "Neues Emoji hinzufügen, das für alle verfügbar sein wird. (Tipp: per Drag & Drop kannst du gleichzeitig mehrere Dateien hinzufügen)"
diff --git a/config/locales/client.es.yml b/config/locales/client.es.yml
index 93c415226e..c7d88e90c8 100644
--- a/config/locales/client.es.yml
+++ b/config/locales/client.es.yml
@@ -660,7 +660,7 @@ es:
undo_revoke_access: "Deshacer revocación de acceso"
api_approved: "Aprobado:"
api_last_used_at: "Fecha de último uso:"
- theme: "Theme"
+ theme: "Tema"
home: "Página de inicio por defecto"
staged: "Temporal"
staff_counters:
@@ -1390,7 +1390,7 @@ es:
one: "
{{username}}, {{username2}} and 1 mas {{description}}"
other: "
{{username}}, {{username2}} y otros {{count}} {{description}}"
liked_consolidated_description:
- one: "le ha dado me gusta a 1 de tus mensaje"
+ one: "le ha dado me gusta a {{count}} de tus mensajes"
other: "le ha dado me gusta a {{count}} de tus mensajes"
liked_consolidated: "
{{username}} {{description}}"
private_message: "
{{username}} {{description}}"
@@ -1667,7 +1667,7 @@ es:
auto_delete:
title: "Auto-Eliminar Tema"
auto_bump:
- title: "Actualizar automáticamente la fecha de este tema"
+ title: "Tema Auto-Bump"
reminder:
title: "Recordarme"
status_update_notice:
@@ -3041,13 +3041,13 @@ es:
title: "Personalizar"
long_title: "Personalizaciones del sitio"
preview: "vista previa"
- explain_preview: "Ver el sitio con el theme habilitado"
+ explain_preview: "Ver el sitio con el tema habilitado"
save: "Guardar"
new: "Nuevo"
new_style: "Nuevo Estilo"
import: "Importar"
delete: "Eliminar"
- delete_confirm: "¿Eliminar este theme?"
+ delete_confirm: "¿Eliminar este tema?"
color: "Color"
opacity: "Opacidad"
copy: "Copiar"
@@ -3073,31 +3073,31 @@ es:
beginners_guide_title: "Guía para novatos usando temas de Discourse"
developers_guide_title: "Guía para desarrolladores para temas de Discourse"
browse_themes: "Ver temas de la comunidad"
- import_theme: "Importar Theme"
+ import_theme: "Importar tema"
customize_desc: "Personalizar:"
- title: "Themes"
+ title: "Tema"
create: "Crear"
create_type: "Tipo:"
create_name: "Nombre:"
name_too_short: "El nombre debe tener al menos 4 caracteres de largo."
long_title: "Modifique los colores, los CSS y los contenidos HTML de su sitio"
edit: "Editar"
- edit_confirm: "Este es un theme remoto, si editas CSS/HTML, los cambios serán borrados en la próxima actualización al theme."
+ edit_confirm: "Este es un tema remoto, si editas CSS/HTML, los cambios serán borrados en la próxima actualización del tema."
common: "Común"
desktop: "Escritorio"
mobile: "Móvil"
settings: "Ajustes"
preview: "Vista previa"
- is_default: "Theme habilitado por defecto"
- user_selectable: "Theme puede ser seleccionado por usuarios"
+ is_default: "Tema habilitado por defecto"
+ user_selectable: "Tema puede ser seleccionado por usuarios"
color_scheme: "Esquema de color"
- color_scheme_select: "Selecciona colores para ser usados en el theme"
+ color_scheme_select: "Selecciona colores para ser usados en el tema"
custom_sections: "Personalizaciones:"
- theme_components: "Componentes del Theme"
+ theme_components: "Componentes del tem"
convert: "Convertir"
convert_component_alert: "¿Estás seguro de que quieres convertir este componente en tema? Será eliminado como componente desde %{relatives}."
convert_component_tooltip: "Convertir este componente en tema"
- convert_theme_alert: "¿Estás seguro que quieres convertir este theme en componente? Será eliminado como principal desde %{relatives}."
+ convert_theme_alert: "¿Estás seguro que quieres convertir este tema en componente? Será eliminado como principal desde %{relatives}."
convert_theme_tooltip: "Convertir este tema en componente"
inactive_themes: "Tema inactivos:"
inactive_components: "Componentes sin usar:"
@@ -3107,7 +3107,7 @@ es:
and_x_more: "y {{count}} más."
collapse: Colapsar
uploads: "Subidos"
- no_uploads: "Puedes subir archivos asociados con tu theme como fuentes e imágenes "
+ no_uploads: "Puedes subir archivos asociados con tu tema como fuentes e imágenes "
add_upload: "Agregar Subido"
upload_file_tip: "Selecciona un archivo a subir (png, woff2, etc...)"
variable_name: "Nombre de variable SCSS:"
@@ -3124,10 +3124,10 @@ es:
css_html: "Personalizar CSS/HTML"
edit_css_html: "Editar CSS/HTML"
edit_css_html_help: "No has editado ningún CSS o HTML"
- delete_upload_confirm: "Borrar este upload? (El theme CSS puede dejar de funcionar!)"
- import_web_tip: "Repositorio que contiene el theme"
+ delete_upload_confirm: "¿Borrar este archivo? (¡El tema CSS puede dejar de funcionar!)"
+ import_web_tip: "Repositorio que contiene el tema"
import_file_tip: "archivo .tar.gz o .dcstyle.json que contenga el tema"
- is_private: "El theme está en un repositorio privado de git"
+ is_private: "El tema está en un repositorio privado de git"
remote_branch: "Nombre del Branch (opcional)"
public_key: "Conceda la siguiente clave pública de acceso para el repositorio:"
about_theme: "Acerca de"
@@ -3143,15 +3143,15 @@ es:
update_to_latest: "Actualizar a lo último"
check_for_updates: "Verificar por Actualizaciones"
updating: "Actualizando..."
- up_to_date: "Theme actualizado, última verificación:"
+ up_to_date: "Tema actualizado, última comprobación:"
add: "Agregar"
- theme_settings: "Ajustes del Theme"
- no_settings: "Este theme no tiene ajustes."
+ theme_settings: "Ajustes del tem"
+ no_settings: "Este tema no tiene ajustes."
theme_translations: "Traducciones del tema"
empty: "Sin items"
commits_behind:
- one: "Theme está 1 commit detrás!"
- other: "Theme está {{count}} commits detrás!"
+ one: "¡El tema está 1 commit detrás!"
+ other: "¡El tema está {{count}} commits detrás!"
compare_commits: "(Ver nuevos commits)"
repo_unreachable: "No se ha podido contactar con el repositorio Git de este tema. Mensaje de error:"
imported_from_archive: "Este tema fue importado de un archivo .tar.gz"
@@ -3178,7 +3178,7 @@ es:
title: "HTML que será insertado antes del tag