REFACTOR: Fixes poor class hierarchy for listing topics

- Upgrades Ember to latest
- Fixes a bunch of bugs with page titles and missing "active" states
This commit is contained in:
Robin Ward 2014-01-14 12:48:57 -05:00 committed by Régis Hanol
parent 86214989f5
commit 4981525047
178 changed files with 8441 additions and 4573 deletions

View File

@ -9,10 +9,10 @@
{{#each controller}}
<li>
<div class="left">
<img {{bindAttr src="gravatarUrl"}}>
<img {{bind-attr src="gravatarUrl"}}>
</div>
<div class="right">
<span class="commit-message"><a {{bindAttr href="commitUrl"}} target="_blank">{{ commit.message }}</a></span><br/>
<span class="commit-message"><a {{bind-attr href="commitUrl"}} target="_blank">{{ commit.message }}</a></span><br/>
<span class="commit-meta">{{i18n admin.commits.by}} <span class="committer-name">{{ commit.author.name }}</span> - <span class="commit-time">{{{ timeAgo }}}</span></span>
</div>
</li>

View File

@ -2,7 +2,7 @@
<h3>{{i18n admin.customize.long_title}}</h3>
<ul>
{{#each model}}
<li><a {{action selectStyle this}} {{bindAttr class="this.selected:active"}}>{{this.description}}</a></li>
<li><a {{action selectStyle this}} {{bind-attr class="this.selected:active"}}>{{this.description}}</a></li>
{{/each}}
</ul>
<button {{action newCustomization}} class='btn'>{{i18n admin.customize.new}}</button>
@ -17,16 +17,16 @@
<div class='admin-controls'>
<ul class="nav nav-pills">
<li>
<a {{bindAttr class="view.stylesheetActive:active"}}{{action selectStylesheet href="true" target="view"}}>{{i18n admin.customize.css}}</a>
<a {{bind-attr class="view.stylesheetActive:active"}}{{action selectStylesheet href="true" target="view"}}>{{i18n admin.customize.css}}</a>
</li>
<li>
<a {{bindAttr class="view.headerActive:active"}}{{action selectHeader href="true" target="view"}}>{{i18n admin.customize.header}}</a>
<a {{bind-attr class="view.headerActive:active"}}{{action selectHeader href="true" target="view"}}>{{i18n admin.customize.header}}</a>
</li>
<li>
<a {{bindAttr class="view.mobileStylesheetActive:active"}}{{action selectMobileStylesheet href="true" target="view"}}>{{i18n admin.customize.mobile_css}}</a>
<a {{bind-attr class="view.mobileStylesheetActive:active"}}{{action selectMobileStylesheet href="true" target="view"}}>{{i18n admin.customize.mobile_css}}</a>
</li>
<li>
<a {{bindAttr class="view.mobileHeaderActive:active"}}{{action selectMobileHeader href="true" target="view"}}>{{i18n admin.customize.mobile_header}}</a>
<a {{bind-attr class="view.mobileHeaderActive:active"}}{{action selectMobileHeader href="true" target="view"}}>{{i18n admin.customize.mobile_header}}</a>
</li>
</ul>
</div>
@ -51,14 +51,14 @@
<span>{{i18n admin.customize.override_default}} {{view Ember.Checkbox checkedBinding="selectedItem.override_default_style"}}</span>
<span>{{i18n admin.customize.enabled}} {{view Ember.Checkbox checkedBinding="selectedItem.enabled"}}</span>
{{#unless selectedItem.changed}}
<a class='preview-link' {{bindAttr href="selectedItem.previewUrl"}} target='_blank'>{{i18n admin.customize.preview}}</a>
<a class='preview-link' {{bind-attr href="selectedItem.previewUrl"}} target='_blank'>{{i18n admin.customize.preview}}</a>
|
<a href="/?preview-style=" target='_blank'>{{i18n admin.customize.undo_preview}}</a><br>
{{/unless}}
</div>
<div class='buttons'>
<button {{action save}} {{bindAttr disabled="selectedItem.disableSave"}} class='btn'>{{i18n admin.customize.save}}</button>
<button {{action save}} {{bind-attr disabled="selectedItem.disableSave"}} class='btn'>{{i18n admin.customize.save}}</button>
<span class='saving'>{{selectedItem.savingStatus}}</span>
<a {{action destroy}} class='delete-link'>{{i18n admin.customize.delete}}</a>
</div>

View File

@ -3,9 +3,9 @@
<div class="dashboard-stats detected-problems">
<div class="look-here"><i class="fa fa-exclamation-triangle"></i></div>
<div class="problem-messages">
<p {{bindAttr class="loadingProblems:invisible"}}>
<p {{bind-attr class="loadingProblems:invisible"}}>
{{i18n admin.dashboard.problems_found}}
<ul {{bindAttr class="loadingProblems:invisible"}}>
<ul {{bind-attr class="loadingProblems:invisible"}}>
{{#each problem in problems}}
<li>{{{problem}}}</li>
{{/each}}
@ -34,7 +34,7 @@
{{/if}}
{{#if Discourse.SiteSettings.version_checks}}
<div {{bindAttr class=":dashboard-stats :version-check versionCheck.critical_updates:critical:normal"}}>
<div {{bind-attr class=":dashboard-stats :version-check versionCheck.critical_updates:critical:normal"}}>
<table class="table table-condensed table-hover">
<thead>
<tr>
@ -48,7 +48,7 @@
{{#unless loading}}
<tbody>
<td class="title">{{i18n admin.dashboard.version}}</td>
<td class="version-number"><a {{bindAttr href="versionCheck.gitLink"}} target="_blank">{{ versionCheck.installed_version }}</a></td>
<td class="version-number"><a {{bind-attr href="versionCheck.gitLink"}} target="_blank">{{ versionCheck.installed_version }}</a></td>
{{#if versionCheck.noCheckPerformed}}
<td class="version-number">&nbsp;</td>
@ -83,7 +83,7 @@
{{#if versionCheck.upToDate }}
<span class='icon up-to-date'>☻</span>
{{else}}
<span {{bindAttr class=":icon versionCheck.critical_updates:critical-updates-available:updates-available"}}>
<span {{bind-attr class=":icon versionCheck.critical_updates:critical-updates-available:updates-available"}}>
{{#if versionCheck.behindByOneVersion}}
{{else}}
@ -291,4 +291,4 @@
<div class="pull-right">{{i18n admin.dashboard.last_updated}} {{updatedTimestamp}}</div>
<div class='clearfix'></div>
</div>
<div class='clearfix'></div>
<div class='clearfix'></div>

View File

@ -10,4 +10,4 @@
<div class="admin-container">
{{outlet}}
</div>
</div>

View File

@ -17,7 +17,7 @@
{{textField value=testEmailAddress placeholderKey="admin.email.test_email_address"}}
</div>
<div class='span10 controls'>
<button class='btn' {{action sendTestEmail}} {{bindAttr disabled="sendTestEmailDisabled"}}>{{i18n admin.email.send_test}}</button>
<button class='btn' {{action sendTestEmail}} {{bind-attr disabled="sendTestEmailDisabled"}}>{{i18n admin.email.send_test}}</button>
{{#if sentTestEmail}}<span class='result-message'>{{i18n admin.email.sent_test}}</span>{{/if}}
</div>
</div>

View File

@ -24,7 +24,7 @@
</thead>
<tbody>
{{#each flaggedPost in content}}
<tr {{bindAttr class="flaggedPost.extraClasses"}}>
<tr {{bind-attr class="flaggedPost.extraClasses"}}>
<td class='user'>{{#if flaggedPost.user}}{{#link-to 'adminUser' flaggedPost.user}}{{avatar flaggedPost.user imageSize="small"}}{{/link-to}}{{/if}}</td>

View File

@ -4,12 +4,12 @@
<ul>
{{#each group in model}}
<li>
<a href="#" {{action "edit" group}} {{bindAttr class="group.active"}}>{{group.name}} <span class="count">{{group.userCountDisplay}}</span></a>
<a href="#" {{action "edit" group}} {{bind-attr class="group.active"}}>{{group.name}} <span class="count">{{group.userCountDisplay}}</span></a>
</li>
{{/each}}
</ul>
<div class='controls'>
<button class='btn' {{bindAttr disabled="refreshingAutoGroups"}} {{action "refreshAutoGroups"}}>Refresh</button>
<button class='btn' {{bind-attr disabled="refreshingAutoGroups"}} {{action "refreshAutoGroups"}}>Refresh</button>
<button class='btn' {{action newGroup}}>New</button>
</div>
</div>
@ -37,7 +37,7 @@
</div>
</div>
<div class='controls'>
<button {{action save this}} {{bindAttr disabled="disableSave"}} class='btn'>{{i18n admin.customize.save}}</button>
<button {{action save this}} {{bind-attr disabled="disableSave"}} class='btn'>{{i18n admin.customize.save}}</button>
{{#unless automatic}}
<a {{action destroy this}} class='delete-link'>{{i18n admin.customize.delete}}</a>
{{/unless}}

View File

@ -11,4 +11,4 @@
<div class="admin-container">
{{outlet}}
</div>
</div>

View File

@ -19,4 +19,4 @@
</section>
<section class="field">
<b>{{i18n admin.customize.override_default}}</b>: {{override_default_style}}
</section>
</section>

View File

@ -3,4 +3,4 @@
</div>
<div class="modal-footer">
<button class='btn btn-primary' {{action closeModal}}>{{i18n close}}</button>
</div>
</div>

View File

@ -22,4 +22,4 @@
{{else}}
{{i18n search.no_results}}
{{/if}}
{{/if}}
{{/if}}

View File

@ -1,9 +1,9 @@
<div class="col first email">
<div class="overflow-ellipsis" {{bindAttr title="email"}}>{{email}}</div>
<div class="overflow-ellipsis" {{bind-attr title="email"}}>{{email}}</div>
</div>
<div class="col action">{{actionName}}</div>
<div class="col match_count">{{match_count}}</div>
<div class="col last_match_at">{{unboundAgeWithTooltip last_match_at}}</div>
<div class="col created_at">{{unboundAgeWithTooltip created_at}}</div>
<div class="col ip_address">{{ip_address}}</div>
<div class="clearfix"></div>
<div class="clearfix"></div>

View File

@ -25,4 +25,4 @@
{{else}}
{{i18n search.no_results}}
{{/if}}
{{/if}}
{{/if}}

View File

@ -6,7 +6,7 @@
{{/if}}
</div>
<div class="col action">
<i {{bindAttr class=":fa actionIcon"}}></i>
<i {{bind-attr class=":fa actionIcon"}}></i>
{{actionName}}
</div>
<div class="col match_count">{{match_count}}</div>
@ -21,13 +21,13 @@
<button class="btn btn-danger" {{action destroy this}}><i class="fa fa-trash-o"></i> {{i18n admin.logs.delete}}</button>
<button class="btn" {{action edit this}}><i class="fa fa-pencil"></i> {{i18n admin.logs.edit}}</button>
{{#if isBlocked}}
<button class="btn" {{action allow this}}><i {{bindAttr class=":fa doNothingIcon"}}></i> {{i18n admin.logs.screened_ips.actions.do_nothing}}</button>
<button class="btn" {{action allow this}}><i {{bind-attr class=":fa doNothingIcon"}}></i> {{i18n admin.logs.screened_ips.actions.do_nothing}}</button>
{{else}}
<button class="btn" {{action block this}}><i {{bindAttr class=":fa blockIcon"}}></i> {{i18n admin.logs.screened_ips.actions.block}}</button>
<button class="btn" {{action block this}}><i {{bind-attr class=":fa blockIcon"}}></i> {{i18n admin.logs.screened_ips.actions.block}}</button>
{{/if}}
{{else}}
<button class="btn" {{action save this}}>{{i18n admin.logs.save}}</button>
<a {{action cancel this}}>{{i18n cancel}}</a>
{{/unless}}
</div>
<div class="clearfix"></div>
<div class="clearfix"></div>

View File

@ -21,4 +21,4 @@
{{else}}
{{i18n search.no_results}}
{{/if}}
{{/if}}
{{/if}}

View File

@ -1,8 +1,8 @@
<div class="col first domain">
<div class="overflow-ellipsis" {{bindAttr title="domain"}}>{{domain}}</div>
<div class="overflow-ellipsis" {{bind-attr title="domain"}}>{{domain}}</div>
</div>
<div class="col action">{{actionName}}</div>
<div class="col match_count">{{match_count}}</div>
<div class="col last_match_at">{{unboundAgeWithTooltip last_match_at}}</div>
<div class="col created_at">{{unboundAgeWithTooltip created_at}}</div>
<div class="clearfix"></div>
<div class="clearfix"></div>

View File

@ -1,14 +1,14 @@
<div>
<ul class="nav nav-pills">
<li {{bindAttr class="newSelected:active"}}>
<li {{bind-attr class="newSelected:active"}}>
<a href="#" {{action selectNew}}>{{i18n admin.logs.staff_actions.new_value}}</a>
</li>
<li {{bindAttr class="previousSelected:active"}}>
<li {{bind-attr class="previousSelected:active"}}>
<a href="#" {{action selectPrevious}}>{{i18n admin.logs.staff_actions.previous_value}}</a>
</li>
</ul>
<div class="modal-body">
<div {{bindAttr class=":modal-tab :new-tab newSelected::invisible"}}>
<div {{bind-attr class=":modal-tab :new-tab newSelected::invisible"}}>
{{#if new_value}}
{{#with new_value}}
{{partial "admin/templates/logs/site_customization_change_details"}}
@ -17,7 +17,7 @@
{{i18n admin.logs.staff_actions.deleted}}
{{/if}}
</div>
<div {{bindAttr class=":modal-tab :previous-tab previousSelected::invisible"}}>
<div {{bind-attr class=":modal-tab :previous-tab previousSelected::invisible"}}>
{{#if previous_value}}
{{#with previous_value}}
{{partial "admin/templates/logs/site_customization_change_details"}}
@ -30,4 +30,4 @@
<div class="modal-footer">
<button class='btn btn-primary' {{action closeModal}}>{{i18n close}}</button>
</div>
</div>
</div>

View File

@ -1,5 +1,5 @@
<div class="staff-action-logs-controls">
<a {{action clearAllFilters}} {{bindAttr class=":clear-filters :filter filtersExists::invisible"}}>
<a {{action clearAllFilters}} {{bind-attr class=":clear-filters :filter filtersExists::invisible"}}>
<span class="label">{{i18n admin.logs.staff_actions.clear_filters}}</span>
</a>
{{#if actionFilter}}
@ -28,7 +28,7 @@
{{/if}}
</div>
<div class="staff-action-logs-instructions" {{bindAttr class=":staff-action-logs-instructions showInstructions::invisible"}}>
<div class="staff-action-logs-instructions" {{bind-attr class=":staff-action-logs-instructions showInstructions::invisible"}}>
{{i18n admin.logs.staff_actions.instructions}}
</div>

View File

@ -11,7 +11,7 @@
<a {{action filterByTargetUser target_user}} class="btn btn-small">{{target_user.username}}</a>
{{/if}}
{{#if subject}}
<a {{action filterBySubject subject}} {{bindAttr title="subject"}} class="btn btn-small">{{subject}}</a>
<a {{action filterBySubject subject}} {{bind-attr title="subject"}} class="btn btn-small">{{subject}}</a>
{{/if}}
</div>
<div class="col value created_at">{{unboundAgeWithTooltip created_at}}</div>

View File

@ -3,11 +3,11 @@
<button class='btn'
{{action viewAsTable}}
{{bindAttr disabled="viewingTable"}}>{{i18n admin.dashboard.reports.view_table}}</button>
{{bind-attr disabled="viewingTable"}}>{{i18n admin.dashboard.reports.view_table}}</button>
<button class='btn'
{{action viewAsBarChart}}
{{bindAttr disabled="viewingBarChart"}}>{{i18n admin.dashboard.reports.view_chart}}</button>
{{bind-attr disabled="viewingBarChart"}}>{{i18n admin.dashboard.reports.view_chart}}</button>
<table class='table report'>
<tr>
@ -34,4 +34,4 @@
{{else}}
{{i18n loading}}
{{/if}}
{{/if}}

View File

@ -1,7 +1,7 @@
<tr>
<td class="title"><a {{bindAttr href="reportUrl"}}>{{title}}</a></td>
<td class="title"><a {{bind-attr href="reportUrl"}}>{{title}}</a></td>
<td class="value">{{todayCount}}</td>
<td class="value">{{yesterdayCount}}</td>
<td class="value">{{sevenDaysAgoCount}}</td>
<td class="value">{{thirtyDaysAgoCount}}</td>
</tr>
</tr>

View File

@ -1,13 +1,13 @@
<tr>
<td class="title">
{{#if icon}}
<i {{bindAttr class=":fa icon"}}></i>
<i {{bind-attr class=":fa icon"}}></i>
{{/if}}
<a {{bindAttr href="reportUrl"}}>{{title}}</a>
<a {{bind-attr href="reportUrl"}}>{{title}}</a>
</td>
<td class="value">{{todayCount}}</td>
<td {{bindAttr class=":value yesterdayTrend"}} {{bindAttr title="yesterdayCountTitle"}}>{{yesterdayCount}} <i class="fa up fa-caret-up"></i><i class="fa down fa-caret-down"></i></td>
<td {{bindAttr class=":value sevenDayTrend"}} {{bindAttr title="sevenDayCountTitle"}}>{{lastSevenDaysCount}} <i class="fa up fa-caret-up"></i><i class="fa down fa-caret-down"></i></td>
<td {{bindAttr class=":value thirtyDayTrend"}} {{bindAttr title="thirtyDayCountTitle"}}>{{lastThirtyDaysCount}} <i class="fa up fa-caret-up"></i><i class="fa down fa-caret-down"></i></td>
<td {{bind-attr class=":value yesterdayTrend"}} {{bind-attr title="yesterdayCountTitle"}}>{{yesterdayCount}} <i class="fa up fa-caret-up"></i><i class="fa down fa-caret-down"></i></td>
<td {{bind-attr class=":value sevenDayTrend"}} {{bind-attr title="sevenDayCountTitle"}}>{{lastSevenDaysCount}} <i class="fa up fa-caret-up"></i><i class="fa down fa-caret-down"></i></td>
<td {{bind-attr class=":value thirtyDayTrend"}} {{bind-attr title="thirtyDayCountTitle"}}>{{lastThirtyDaysCount}} <i class="fa up fa-caret-up"></i><i class="fa down fa-caret-down"></i></td>
<td class="value">{{total}}</td>
</tr>
</tr>

View File

@ -5,4 +5,4 @@
<td class="value">{{#link-to 'adminUsersList.regular'}}{{valueAtTrustLevel data 2}}{{/link-to}}</td>
<td class="value">{{#link-to 'adminUsersList.leaders'}}{{valueAtTrustLevel data 3}}{{/link-to}}</td>
<td class="value">{{#link-to 'adminUsersList.elders'}}{{valueAtTrustLevel data 4}}{{/link-to}}</td>
</tr>
</tr>

View File

@ -15,7 +15,7 @@
{{/if}}
<div class='controls'>
<button class='btn' {{action saveChanges}} {{bindAttr disabled="saveDisabled"}}>
<button class='btn' {{action saveChanges}} {{bind-attr disabled="saveDisabled"}}>
{{#if saving}}
{{i18n saving}}
{{else}}

View File

@ -1 +1 @@
<p>{{i18n admin.site_content.none}}</p>
<p>{{i18n admin.site_content.none}}</p>

View File

@ -14,7 +14,7 @@
<div class="site-settings-nav pull-left">
<ul class="nav nav-stacked">
{{#each category in controller}}
<li {{bindAttr class="category.nameKey"}}>
<li {{bind-attr class="category.nameKey"}}>
{{#link-to 'adminSiteSettingsCategory' category.nameKey class=category.nameKey}}
{{category.name}}
{{#if filtered}}

View File

@ -3,4 +3,4 @@
{{else}}
<br/>
{{i18n admin.site_settings.no_results}}
{{/if}}
{{/if}}

View File

@ -198,7 +198,7 @@
</div>
</div>
<div {{bindAttr class=":display-row isSuspended:highlight-danger"}}>
<div {{bind-attr class=":display-row isSuspended:highlight-danger"}}>
<div class='field'>{{i18n admin.user.suspended}}</div>
<div class='value'>{{isSuspended}}</div>
<div class='controls'>
@ -235,7 +235,7 @@
</div>
{{/if}}
<div class='display-row' {{bindAttr class=":display-row blocked:highlight-danger"}}>
<div class='display-row' {{bind-attr class=":display-row blocked:highlight-danger"}}>
<div class='field'>{{i18n admin.user.blocked}}</div>
<div class='value'>{{blocked}}</div>
<div class='controls'>
@ -313,7 +313,7 @@
<section>
<hr/>
<button {{bindAttr class=":btn :btn-danger :pull-right deleteForbidden:hidden"}} {{action destroy target="content"}} {{bindAttr disabled="deleteForbidden"}} {{bindAttr}}>
<button {{bind-attr class=":btn :btn-danger :pull-right deleteForbidden:hidden"}} {{action destroy target="content"}} {{bind-attr disabled="deleteForbidden"}} {{bind-attr}}>
<i class="fa fa-exclamation-triangle"></i>
{{i18n admin.user.delete}}
</button>

View File

@ -54,7 +54,7 @@
</tr>
{{#each model}}
<tr {{bindAttr class="selected"}}>
<tr {{bind-attr class="selected"}}>
{{#if controller.showApproval}}
<td>
{{#if can_approve}}
@ -94,4 +94,4 @@
<p>{{i18n search.no_results}}</p>
{{/if}}
{{/if}}
</div>
</div>

View File

@ -29,9 +29,11 @@ Discourse.BreadCrumbsComponent = Ember.Component.extend({
}.property('category', 'parentCategory'),
childCategories: function() {
var self = this;
var firstCategory = this.get('firstCategory');
if (!firstCategory) { return; }
return this.get('categories').filter(function (c) {
return c.get('parentCategory') === self.get('firstCategory');
return c.get('parentCategory') === firstCategory;
});
}.property('firstCategory')

View File

@ -56,6 +56,10 @@ Discourse.CategoryDropComponent = Ember.Component.extend({
var self = this,
$dropdown = this.$()[0];
this.$('a[data-drop-close]').on('click.category-drop', function() {
self.close();
});
$('html').on('click.category-drop', function(e) {
var $target = $(e.target),
closest = $target.closest($dropdown);
@ -71,11 +75,13 @@ Discourse.CategoryDropComponent = Ember.Component.extend({
close: function() {
$('html').off('click.category-drop');
this.$('a[data-drop-close]').off('click.category-drop');
this.set('expanded', false);
},
willDestroyElement: function() {
$('html').off('click.category-drop');
this.$('a[data-drop-close]').off('click.category-drop');
}
});

View File

@ -141,7 +141,7 @@ Discourse.KeyboardShortcuts = Ember.Object.createWithMixins({
},
_changeSection: function(num) {
var $sections = $('#category-filter').find('li'),
var $sections = $('#navigation-bar').find('li'),
index = $sections.index('.active');
$sections.eq(index + num).find('a').click();

View File

@ -1,19 +1,17 @@
/**
This view handles rendering of a navigation item
@class NavItemView
@extends Discourse.View
@class NavigationItemComponent
@extends Ember.Component
@namespace Discourse
@module Discourse
**/
Discourse.NavItemView = Discourse.View.extend({
Discourse.NavigationItemComponent = Ember.Component.extend({
tagName: 'li',
classNameBindings: ['active', 'content.hasIcon:has-icon'],
attributeBindings: ['title'],
hidden: Em.computed.not('content.visible'),
shouldRerender: Discourse.View.renderIfChanged('content.count'),
active: Discourse.computed.propertyEqual('content.filterMode', 'controller.filterMode'),
title: function() {
var categoryName = this.get('content.categoryName'),
@ -27,13 +25,15 @@ Discourse.NavItemView = Discourse.View.extend({
return I18n.t("filters." + name + ".help", extra);
}.property("content.name"),
active: function() {
return this.get('content.filterMode') === this.get('filterMode') ||
(this.get('filterMode') === 'top' && this.get('content.filterMode').indexOf('top') >= 0);
}.property('content.filterMode', 'filterMode'),
name: function() {
var categoryName = this.get('content.categoryName'),
name = this.get('content.name'),
extra = {
count: this.get('content.count') || 0
};
extra = { count: this.get('content.count') || 0 };
if (categoryName) {
name = 'category';
@ -51,7 +51,4 @@ Discourse.NavItemView = Discourse.View.extend({
buffer.push(this.get('name'));
buffer.push("</a>");
}
});

View File

@ -6,12 +6,18 @@
@namespace Discourse
@module Discourse
**/
Discourse.ToggleSummaryComponent = Ember.Component.extend({
Discourse.ToggleSummaryComponent = Ember.View.extend({
templateName: 'components/toggle-summary',
tagName: 'section',
classNames: ['information'],
postStream: Em.computed.alias('topic.postStream'),
init: function() {
this._super();
this.set('context', this);
this.set('controller', this);
},
actions: {
toggleSummary: function() {
this.get('postStream').toggleSummary();

View File

@ -9,7 +9,7 @@
var LINKS_SHOWN = 5;
Discourse.TopicMapComponent = Ember.Component.extend({
Discourse.TopicMapComponent = Ember.View.extend({
mapCollapsed: true,
templateName: 'components/topic-map',
details: Em.computed.alias('topic.details'),
@ -18,6 +18,9 @@ Discourse.TopicMapComponent = Ember.Component.extend({
init: function() {
this._super();
this.set('context', this);
this.set('controller', this);
// If the topic has a summary, expand the map by default
this.set('mapCollapsed', Discourse.Mobile.mobileView || (!this.get('topic.has_summary')));
},

View File

@ -283,7 +283,7 @@ Discourse.ComposerController = Discourse.Controller.extend({
} else {
opts.tested = true;
if (!opts.ignoreIfChanged) {
this.cancelComposer().then(function() { self.open(opts); }).fail(function() { return promise.reject(); });
this.cancelComposer().then(function() { self.open(opts); }).catch(function() { return promise.reject(); });
}
return promise;
}

View File

@ -1,12 +1,12 @@
/**
This controller supports actions when listing categories
@class ListCategoriesController
@class DiscoveryCategoriesController
@extends Discourse.ObjectController
@namespace Discourse
@module Discourse
**/
Discourse.ListCategoriesController = Discourse.ObjectController.extend({
Discourse.DiscoveryCategoriesController = Discourse.ObjectController.extend({
needs: ['modal'],
actions: {
@ -33,5 +33,3 @@ Discourse.ListCategoriesController = Discourse.ObjectController.extend({
}.property('categories.@each.featuredTopics.length')
});

View File

@ -1,12 +1,13 @@
/**
Controller of the top page
The controller for discoverying "Top" topics
@class ListTopController
@extends Discourse.ObjectController
@class DiscoveryTopController
@extends Discourse.Controller
@namespace Discourse
@module Discourse
**/
Discourse.ListTopController = Discourse.ObjectController.extend({
Discourse.DiscoveryTopController = Discourse.ObjectController.extend({
category:null,
redirectedToTopPageReason: function() {
// no need for a reason if the default homepage is "top"
@ -36,5 +37,4 @@ Discourse.ListTopController = Discourse.ObjectController.extend({
showMoreWeeklyUrl: function() { return this.showMoreUrl("weekly"); }.property("category.url"),
showMoreMonthlyUrl: function() { return this.showMoreUrl("monthly"); }.property("category.url"),
showMoreYearlyUrl: function() { return this.showMoreUrl("yearly"); }.property("category.url"),
});

View File

@ -1,40 +1,12 @@
/**
This controller supports actions when listing topics or categories
The controller for displaying a list of topics.
@class ListTopicsController
@extends Discourse.ObjectController
@class DiscoveryTopicsController
@extends Discourse.Controller
@namespace Discourse
@module Discourse
**/
Discourse.ListTopicsController = Discourse.ObjectController.extend({
needs: ['list', 'composer', 'modal'],
rankDetailsVisible: false,
// If we're changing our channel
previousChannel: null,
latest: Ember.computed.equal('filter', 'latest'),
topicListReloading: function() {
return (!this.get('controllers.list.loading')) && (!this.get('loaded'));
}.property('loaded', 'controllers.list.loading'),
categories: function() {
return Discourse.Category.list();
}.property(),
draftLoaded: function() {
var draft = this.get('content.draft');
if (draft) {
return this.get('controllers.composer').open({
draft: draft,
draftKey: this.get('content.draft_key'),
draftSequence: this.get('content.draft_sequence'),
ignoreIfChanged: true
});
}
}.observes('content.draft'),
Discourse.DiscoveryTopicsController = Discourse.ObjectController.extend({
actions: {
// Star a topic
toggleStar: function(topic) {
@ -46,14 +18,6 @@ Discourse.ListTopicsController = Discourse.ObjectController.extend({
topic.clearPin();
},
toggleRankDetails: function() {
this.toggleProperty('rankDetailsVisible');
},
createTopic: function() {
this.get('controllers.list').send('createTopic');
},
// Show newly inserted topics
showInserted: function() {
var tracker = Discourse.TopicTrackingState.current();
@ -62,17 +26,36 @@ Discourse.ListTopicsController = Discourse.ObjectController.extend({
this.get('content').loadBefore(tracker.get('newIncoming'));
tracker.resetTracking();
return false;
},
refresh: function() {
var filter = this.get('model.filter'),
self = this;
this.send('loading');
Discourse.TopicList.find(filter).then(function(list) {
self.set('model', list);
self.send('loadingComplete');
});
}
},
allLoaded: function() {
return !this.get('loading') && !this.get('more_topics_url');
}.property('loading', 'more_topics_url'),
topicTrackingState: function() {
return Discourse.TopicTrackingState.current();
}.property(),
canCreateTopic: Em.computed.alias('controllers.list.canCreateTopic'),
hasTopics: Em.computed.gt('topics.length', 0),
showTable: Em.computed.or('hasTopics', 'topicTrackingState.hasIncoming'),
latest: Ember.computed.equal('filter', 'latest'),
allLoaded: Em.computed.empty('more_topics_url'),
updateTitle: function(){
Discourse.notifyTitle(this.get('topicTrackingState.incomingCount'));
}.observes('topicTrackingState.incomingCount'),
footerMessage: function() {
if (!this.get('allLoaded')) return;
if (!this.get('allLoaded')) { return; }
var category = this.get('category');
if( category ) {
return I18n.t('topics.bottom.category', {category: category.get('name')});
@ -90,7 +73,7 @@ Discourse.ListTopicsController = Discourse.ObjectController.extend({
}
}.property('allLoaded', 'topics.length'),
loadMore: function() {
loadMoreTopics: function() {
var topicList = this.get('model');
return topicList.loadMore().then(function(moreUrl) {
if (!Em.isEmpty(moreUrl)) {
@ -98,7 +81,4 @@ Discourse.ListTopicsController = Discourse.ObjectController.extend({
}
});
}
});

View File

@ -155,7 +155,7 @@ Discourse.EditCategoryController = Discourse.ObjectController.extend(Discourse.M
model.setProperties({slug: result.category.slug, id: result.category.id });
Discourse.URL.redirectTo("/category/" + Discourse.Category.slugFor(model));
}).fail(function(error) {
}).catch(function(error) {
if (error && error.responseText) {
self.flash($.parseJSON(error.responseText).errors[0]);
} else {

View File

@ -92,7 +92,7 @@ Discourse.InviteController = Discourse.ObjectController.extend(Discourse.ModalFu
this.setProperties({ saving: true, error: false });
this.get('model').createInvite(this.get('email')).then(function() {
self.setProperties({ saving: false, finished: true });
}).fail(function() {
}).catch(function() {
self.setProperties({ saving: false, error: true });
});
return false;

View File

@ -39,7 +39,7 @@ Discourse.InvitePrivateController = Discourse.ObjectController.extend(Discourse.
if(result && result.user) {
self.get('model.details.allowed_users').pushObject(result.user);
}
}).fail(function() {
}).catch(function() {
self.setProperties({error: true, saving: false});
});
return false;

View File

@ -1,138 +0,0 @@
/**
This controller supports actions when listing topics or categories
@class ListController
@extends Discourse.Controller
@namespace Discourse
@module Discourse
**/
Discourse.ListController = Discourse.Controller.extend({
categoryBinding: "topicList.category",
canCreateCategory: false,
canCreateTopic: false,
needs: ["composer", "modal", "listTopics"],
availableNavItems: function() {
var category = this.get("category");
return Discourse.SiteSettings.top_menu.split("|").map(function(i) {
return Discourse.NavItem.fromText(i, {
loggedOn: !!Discourse.User.current(),
category: category
});
}).filter(function(i) {
return i !== null && !(category && i.get("name").indexOf("categor") === 0);
});
}.property("category"),
/**
Refresh our current topic list
@method refresh
**/
refresh: function() {
var listTopicsController = this.get('controllers.listTopics');
listTopicsController.set('model.loaded', false);
this.load(this.get('filterMode')).then(function (topicList) {
listTopicsController.set('model', topicList);
});
},
/**
Load a list based on a filter
@method load
@param {String} filterMode the filter we want to load
@param {Object} params for additional filtering
@returns {Ember.Deferred} the promise that will resolve to the list of items.
**/
load: function(filterMode, params) {
var self = this;
this.set('loading', true);
var trackingState = Discourse.TopicTrackingState.current();
if (filterMode === 'categories') {
return Discourse.CategoryList.list(filterMode).then(function(items) {
self.setProperties({
loading: false,
filterMode: filterMode,
categoryMode: true,
draft: items.draft,
draft_key: items.draft_key,
draft_sequence: items.draft_sequence
});
if(trackingState) {
trackingState.sync(items, filterMode);
trackingState.trackIncoming(filterMode);
}
return items;
});
}
var current = (this.get('availableNavItems').filter(function(f) { return f.name === filterMode; }))[0];
if (!current) {
current = Discourse.NavItem.create({ name: filterMode });
}
params = params || {};
return Discourse.TopicList.list(current, params).then(function(items) {
self.setProperties({
loading: false,
filterMode: filterMode,
draft: items.draft,
draft_key: items.draft_key,
draft_sequence: items.draft_sequence,
noSubcategories: params.no_subcategories
});
if(trackingState) {
trackingState.sync(items, filterMode);
trackingState.trackIncoming(filterMode);
}
return items;
});
},
// Put in the appropriate page title based on our view
updateTitle: function() {
if (this.get('filterMode') === 'categories') {
Discourse.set('title', I18n.t('categories_list'));
} else {
if (this.present('category')) {
Discourse.set('title', this.get('category.name').capitalize() + " " + I18n.t('topic.list'));
} else {
Discourse.set('title', I18n.t('topic.list'));
}
}
}.observes('filterMode', 'category'),
// Create topic button
actions: {
createTopic: function() {
this.get('controllers.composer').open({
categoryId: this.get('category.id'),
action: Discourse.Composer.CREATE_TOPIC,
draft: this.get('draft'),
draftKey: this.get('draft_key'),
draftSequence: this.get('draft_sequence')
});
}
},
canEditCategory: function() {
if( this.present('category') ) {
var u = Discourse.User.current();
return u && u.staff;
} else {
return false;
}
}.property('category'),
categories: function() {
return Discourse.Category.list();
}.property()
});
Discourse.ListController.reopenClass({
FILTERS: <%= Discourse.filters.map(&:to_s) %>
});

View File

@ -0,0 +1,40 @@
/**
Handles the controller for the default navigation within discovery.
@class NavigationDefaultController
@extends Discourse.Controller
@namespace Discourse
@module Discourse
**/
Discourse.NavigationDefaultController = Discourse.Controller.extend({
needs: ['composer', 'discoveryTopics'],
actions: {
createTopic: function() {
var topicsController = this.get('controllers.discoveryTopics');
this.get('controllers.composer').open({
categoryId: this.get('category.id'),
action: Discourse.Composer.CREATE_TOPIC,
draft: topicsController.get('draft'),
draftKey: topicsController.get('draft_key'),
draftSequence: topicsController.get('draft_sequence')
});
}
},
categories: function() {
return Discourse.Category.list();
}.property(),
navItems: function() {
return Discourse.NavItem.buildList();
}.property()
});
Discourse.NavigationCategoryController = Discourse.NavigationDefaultController.extend({
navItems: function() {
return Discourse.NavItem.buildList(this.get('category'), { noSubcategories: this.get('noSubcategories') });
}.property('category', 'noSubcategories')
});
Discourse.NavigationCategoriesController = Discourse.NavigationDefaultController.extend({});

View File

@ -93,9 +93,9 @@ Handlebars.registerHelper('titledLinkTo', function(name, object) {
options.hash.title = I18n.t(options.hash.titleKey);
}
if (arguments.length === 3) {
return Ember.Handlebars.helpers.linkTo.call(this, name, object, options);
return Ember.Handlebars.helpers['link-to'].call(this, name, object, options);
} else {
return Ember.Handlebars.helpers.linkTo.call(this, name, options);
return Ember.Handlebars.helpers['link-to'].call(this, name, options);
}
});

View File

@ -2,6 +2,10 @@
Initialize the message bus to receive messages.
**/
Discourse.addInitializer(function() {
// We don't use the message bus in testing
if (Discourse.testing) { return; }
Discourse.MessageBus.alwaysLongPoll = Discourse.Environment === "development";
Discourse.MessageBus.start();
Discourse.MessageBus.subscribe("/global/asset-version", function(version){

View File

@ -188,11 +188,11 @@ Discourse.URL = Em.Object.createWithMixins({
@param {String} path the path we're navigating to
**/
navigatedToHome: function(oldPath, path) {
var defaultFilter = "/" + Discourse.ListController.FILTERS[0];
var defaultFilter = "/" + Discourse.Site.currentProp('filters')[0];
if (path === "/" && (oldPath === "/" || oldPath === defaultFilter)) {
// Refresh our list
this.controllerFor('list').refresh();
this.controllerFor('discoveryTopics').send('refresh');
return true;
}

View File

@ -180,6 +180,7 @@ Discourse.Utilities = {
@returns true whenever the upload is valid
**/
validateUploadedFile: function(file, type) {
// check that the uploaded file is authorized
if (!Discourse.Utilities.isAuthorizedUpload(file)) {
var extensions = Discourse.Utilities.authorizedExtensions();

View File

@ -44,7 +44,9 @@ Discourse.NavItem = Discourse.Model.extend({
if(category){
mode += "category/";
mode += Discourse.Category.slugFor(this.get('category')) + "/l/";
mode += Discourse.Category.slugFor(this.get('category'));
if (this.get('noSubcategories')) { mode += '/none'; }
mode += "/l/";
}
return mode + name.replace(' ', '-');
}
@ -55,36 +57,37 @@ Discourse.NavItem = Discourse.Model.extend({
if (state) {
return state.lookupCount(this.get('name'), this.get('category'));
}
}.property('topicTrackingState.messageCount'),
excludeCategory: function() {
if (parseInt(this.get('filters.length'), 10) > 0) {
return this.get('filters')[0].substring(1);
}
}.property('filters.length')
}.property('topicTrackingState.messageCount')
});
Discourse.NavItem.reopenClass({
NAMES: <%= Discourse.top_menu_items.map(&:to_s) %>,
ANONYMOUS_NAMES: <%= Discourse.anonymous_top_menu_items.map(&:to_s) %>,
// create a nav item from the text, will return null if there is not valid nav item for this particular text
fromText: function(text, opts) {
var split = text.split(","),
name = split[0],
testName = name.split("/")[0];
testName = name.split("/")[0],
anonymous = !Discourse.User.current();
if (!opts.loggedOn && !Discourse.NavItem.ANONYMOUS_NAMES.contains(testName)) return null;
if (anonymous && !Discourse.Site.currentProp('anonymous_top_menu_items').contains(testName)) return null;
if (!Discourse.Category.list() && testName === "categories") return null;
if (!Discourse.NavItem.NAMES.contains(testName)) return null;
if (!Discourse.Site.currentProp('top_menu_items').contains(testName)) return null;
return Discourse.NavItem.create({
name: name,
hasIcon: name === "unread" || name === "starred",
filters: split.splice(1),
category: opts.category,
var args = { name: name, hasIcon: name === "unread" || name === "starred" };
if (opts.category) { args.category = opts.category; }
if (opts.noSubcategories) { args.noSubcategories = true; }
return Discourse.NavItem.create(args);
},
buildList: function(category, args) {
args = args || {};
if (category) { args.category = category }
return Discourse.SiteSettings.top_menu.split("|").map(function(i) {
return Discourse.NavItem.fromText(i, args);
}).filter(function(i) {
return i !== null && !(category && i.get("name").indexOf("categor") === 0);
});
}

View File

@ -251,7 +251,7 @@ Discourse.PostStream = Em.Object.extend({
self.setProperties({ loadingFilter: false, loaded: true });
Discourse.URL.set('queryParams', self.get('streamFilters'));
}).fail(function(result) {
}).catch(function(result) {
self.errorLoading(result);
});
},

View File

@ -10,8 +10,6 @@
Discourse.TopList = Discourse.Model.extend({});
Discourse.TopList.reopenClass({
PERIODS: <%= TopTopic.periods.map(&:to_s) %>,
find: function(period, category) {
return PreloadStore.getAndRemove("top_lists", function() {
var url = "";
@ -22,7 +20,7 @@ Discourse.TopList.reopenClass({
}).then(function (result) {
var topList = Discourse.TopList.create({});
_.each(Discourse.TopList.PERIODS, function(period) {
Discourse.Site.currentProp('periods').forEach(function(period) {
// if there is a list for that period
if (result[period]) {
// instanciate a new topic list with no sorting

View File

@ -191,7 +191,6 @@ Discourse.TopicList.reopenClass({
draft_key: result.topic_list.draft_key,
draft_sequence: result.topic_list.draft_sequence,
draft: result.topic_list.draft,
canViewRankDetails: result.topic_list.can_view_rank_details,
loaded: true
});
@ -210,9 +209,8 @@ Discourse.TopicList.reopenClass({
@param {Object} Any additional params
@returns {Promise} a promise that resolves to the list of topics
**/
list: function(menuItem, params) {
var filter = menuItem.get('name'),
session = Discourse.Session.current(),
list: function(filter, params) {
var session = Discourse.Session.current(),
list = session.get('topicList');
if (list && (list.get('filter') === filter) && window.location.pathname.indexOf('more') > 0) {
@ -221,7 +219,16 @@ Discourse.TopicList.reopenClass({
}
session.setProperties({topicList: null, topicListScrollPos: null});
var findParams = {exclude_category: menuItem.get('excludeCategory')};
var findParams = {};
Discourse.SiteSettings.top_menu.split('|').forEach(function (i) {
if (i.indexOf(filter) === 0) {
var exclude = i.split("-");
if (exclude && exclude.length === 2) {
findParams.exclude_category = exclude[1];
}
}
});
return Discourse.TopicList.find(filter, _.extend(findParams, params || {}));
},

View File

@ -166,7 +166,7 @@ Discourse.TopicTrackingState = Discourse.Model.extend({
},
lookupCount: function(name, category){
var categoryName = Em.get(category, "name");
var categoryName = category ? Em.get(category, "name") : null;
if(name === "new") {
return this.countNew(categoryName);
} else if(name === "unread") {

View File

@ -18,12 +18,10 @@ Discourse.Route.buildRoutes(function() {
router.route(page, { path: '/' + page });
});
this.resource("list", { path: "/" }, function() {
this.resource('discovery', { path: '/' }, function() {
router = this;
// categories
this.route('categories');
// top
this.route('top');
this.route('topCategory', { path: '/category/:slug/l/top' });
@ -31,7 +29,7 @@ Discourse.Route.buildRoutes(function() {
this.route('topCategory', { path: '/category/:parentSlug/:slug/l/top' });
// top by periods
_.each(Discourse.TopList.PERIODS, function(period) {
Discourse.Site.currentProp('periods').forEach(function(period) {
var top = 'top' + period.capitalize();
router.route(top, { path: '/top/' + period });
router.route(top, { path: '/top/' + period + '/more' });
@ -43,8 +41,7 @@ Discourse.Route.buildRoutes(function() {
router.route(top + 'Category', { path: '/category/:parentSlug/:slug/l/top/' + period + '/more' });
});
// filters
_.each(Discourse.ListController.FILTERS, function(filter) {
Discourse.Site.currentProp('filters').forEach(function(filter) {
router.route(filter, { path: '/' + filter });
router.route(filter, { path: '/' + filter + '/more' });
router.route(filter + 'Category', { path: '/category/:slug/l/' + filter });
@ -55,13 +52,14 @@ Discourse.Route.buildRoutes(function() {
router.route(filter + 'Category', { path: '/category/:parentSlug/:slug/l/' + filter + '/more' });
});
this.route('categories');
// default filter for a category
this.route('category', { path: '/category/:slug' });
this.route('category', { path: '/category/:slug/more' });
this.route('categoryNone', { path: '/category/:slug/none' });
this.route('categoryNone', { path: '/category/:slug/none/more' });
this.route('category', { path: '/category/:parentSlug/:slug' });
this.route('category', { path: '/category/:parentSlug/:slug/more' });
// homepage
var homepage = Discourse.User.current() ? Discourse.User.currentProp('homepage') : Discourse.Utilities.defaultHomepage();

View File

@ -0,0 +1,45 @@
/**
The route for handling the "Categories" view
@class DiscoveryCategoriesRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.DiscoveryCategoriesRoute = Discourse.Route.extend({
renderTemplate: function() {
this.render('navigation/categories', { outlet: 'navigation-bar' });
this.render('discovery/categories', { outlet: 'list-container' });
},
beforeModel: function() {
this.controllerFor('navigationCategories').set('filterMode', 'categories');
},
model: function() {
return Discourse.CategoryList.list('categories').then(function(list) {
var tracking = Discourse.TopicTrackingState.current();
if (tracking) {
tracking.sync(list, 'categories');
tracking.trackIncoming('categories');
}
return list;
});
},
setupController: function(controller, model) {
controller.set('model', model);
Discourse.set('title', I18n.t('filters.categories.title'));
this.controllerFor('navigationCategories').set('canCreateCategory', model.get('can_create_category'));
},
actions: {
createCategory: function() {
Discourse.Route.showModal(this, 'editCategory', Discourse.Category.create({
color: 'AB9364', text_color: 'FFFFFF', hotness: 5, group_permissions: [{group_name: 'everyone', permission_type: 1}],
available_groups: Discourse.Site.current().group_names
}));
this.controllerFor('editCategory').set('selectedTab', 'general');
}
},
});

View File

@ -0,0 +1,25 @@
/**
The parent route for all discovery routes. Handles the logic for showing
the loading spinners.
@class DiscoveryRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.DiscoveryRoute = Discourse.Route.extend({
actions: {
loading: function() {
this.controllerFor('discovery').set('loading', true);
},
loadingComplete: function() {
this.controllerFor('discovery').set('loading', false);
},
didTransition: function() {
this.send('loadingComplete');
}
}
});

View File

@ -0,0 +1,119 @@
/**
A builder to create routes for topic discovery.
@function buildTopicRoute
@param {String} filter to create route for
**/
function buildTopicRoute(filter) {
return Discourse.Route.extend({
renderTemplate: function() {
this.render('navigation/default', { outlet: 'navigation-bar' });
this.render('discovery/topics', { controller: 'discoveryTopics', outlet: 'list-container' });
},
beforeModel: function() {
this.controllerFor('navigationDefault').set('filterMode', filter);
},
model: function() {
return Discourse.TopicList.list(filter).then(function(list) {
var tracking = Discourse.TopicTrackingState.current();
if (tracking) {
tracking.sync(list, filter);
tracking.trackIncoming(filter);
}
return list;
});
},
setupController: function(controller, model) {
var filterText = I18n.t('filters.' + filter + '.title', {count: 0});
Discourse.set('title', I18n.t('filters.with_topics', {filter: filterText}));
this.controllerFor('discoveryTopics').set('model', model);
this.controllerFor('navigationDefault').set('canCreateTopic', model.get('can_create_topic'));
}
});
}
/**
A builder to create routes for topic discovery within a category.
@function buildTopicRoute
@param {String} filter to create route for
@param {Object} params with additional options
**/
function buildCategoryRoute(filter, params) {
return Discourse.Route.extend({
renderTemplate: function() {
this.render('navigation/category', { outlet: 'navigation-bar' });
this.render('discovery/topics', { controller: 'discoveryTopics', outlet: 'list-container' });
},
model: function(params) {
return Discourse.Category.findBySlug(params.slug, params.parentSlug);
},
afterModel: function(model) {
var self = this,
noSubcategories = params && !!params.no_subcategories,
filterMode = "category/" + Discourse.Category.slugFor(model) + (noSubcategories ? "/none" : "") + "/l/" + filter,
listFilter = "category/" + Discourse.Category.slugFor(model) + "/l/" + filter;
this.controllerFor('search').set('searchContext', model);
var opts = { category: model, filterMode: filterMode };
opts.noSubcategories = params && params.no_subcategories;
opts.canEditCategory = Discourse.User.current('staff');
this.controllerFor('navigationCategory').setProperties(opts);
return Discourse.TopicList.list(listFilter, params).then(function(list) {
var tracking = Discourse.TopicTrackingState.current();
if (tracking) {
tracking.sync(list, listFilter);
tracking.trackIncoming(listFilter);
}
// If all the categories are the same, we can hide them
var diffCat = list.get('topics').find(function (t) {
return t.get('category') !== model;
});
if (!diffCat) { list.set('hideCategory', true); }
self.set('topics', list);
});
},
setupController: function(controller, model) {
var topics = this.get('topics');
var filterText = I18n.t('filters.' + filter + '.title', {count: 0});
Discourse.set('title', I18n.t('filters.with_category', {filter: filterText, category: model.get('name').capitalize()}));
this.controllerFor('discoveryTopics').set('model', topics);
this.controllerFor('navigationCategory').set('canCreateTopic', topics.get('can_create_topic'));
this.set('topics', null);
},
deactivate: function() {
this._super();
this.controllerFor('search').set('searchContext', null);
}
});
}
// Finally, build all the routes with the helpers we created
Discourse.addInitializer(function() {
Discourse.DiscoveryController = Em.Controller.extend({});
Discourse.DiscoveryCategoryRoute = buildCategoryRoute('latest');
Discourse.DiscoveryCategoryNoneRoute = buildCategoryRoute('latest', {no_subcategories: true});
Discourse.Site.currentProp('filters').forEach(function(filter) {
Discourse["Discovery" + filter.capitalize() + "Route"] = buildTopicRoute(filter);
Discourse["Discovery" + filter.capitalize() + "CategoryRoute"] = buildCategoryRoute(filter);
Discourse["Discovery" + filter.capitalize() + "CategoryNoneRoute"] = buildCategoryRoute(filter, {no_subcategories: true});
});
Discourse.Site.currentProp('periods').forEach(function(period) {
Discourse["DiscoveryTop" + period.capitalize() + "Route"] = buildTopicRoute('top/' + period);
Discourse["DiscoveryTop" + period.capitalize() + "CategoryRoute"] = buildCategoryRoute('top/' + period);
Discourse["DiscoveryTop" + period.capitalize() + "CategoryNoneRoute"] = buildCategoryRoute('top/' + period, {no_subcategories: true});
});
}, true);

View File

@ -0,0 +1,40 @@
/**
Handles the routes related to "Top"
@class DiscoveryTopRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.DiscoveryTopRoute = Discourse.Route.extend({
model: function(params) {
return Discourse.Category.findBySlug(params.slug, params.parentSlug);
},
beforeModel: function() {
this.controllerFor('navigationCategory').set('filterMode', 'top');
},
afterModel: function(model) {
var self = this;
return Discourse.TopList.find(null, model).then(function(list) {
self.set('topics', list);
});
},
renderTemplate: function() {
this.render('navigation/category', { outlet: 'navigation-bar' });
this.render('discovery/top', { outlet: 'list-container' });
},
setupController: function(controller, model) {
this.controllerFor('discoveryTop').set('model', this.get('topics'));
this.controllerFor('discoveryTop').set('category', model);
this.controllerFor('navigationCategory').set('category', model);
Discourse.set('title', I18n.t('filters.top.title'));
this.set('topics', null);
}
});
Discourse.DiscoveryTopCategoryRoute = Discourse.DiscoveryTopRoute.extend({});
Discourse.DiscoveryTopCategoryNoneRoute = Discourse.DiscoveryTopRoute.extend({});

View File

@ -1,62 +0,0 @@
/**
A class used to handle filtering routes such as latest, hot, read, etc.
@class FilteredListRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.FilteredListRoute = Discourse.Route.extend({
redirect: function() { Discourse.redirectIfLoginRequired(this); },
renderTemplate: function() {
this.render('listTopics', { into: 'list', outlet: 'listView', controller: 'listTopics' });
},
setupController: function() {
var listController = this.controllerFor('list'),
listTopicsController = this.controllerFor('listTopics');
listController.set('filterMode', this.filter);
var listContent = listTopicsController.get('model');
if (listContent) {
listContent.set('loaded', false);
}
listController.set('category', null);
listController.load(this.filter).then(function(topicList) {
listController.set('canCreateTopic', topicList.get('can_create_topic'));
listTopicsController.set('model', topicList);
Discourse.FilteredListRoute.scrollToLastPosition();
});
},
deactivate: function() {
this._super();
this.controllerFor('list').setProperties({
canCreateTopic: false,
filterMode: ''
});
},
});
Discourse.FilteredListRoute.reopenClass({
scrollToLastPosition: function() {
var scrollPos = Discourse.Session.currentProp('topicListScrollPosition');
if (scrollPos) {
Em.run.next(function() { $('html, body').scrollTop(scrollPos); });
Discourse.Session.currentProp('topicListScrollPosition', null);
}
}
});
_.each(Discourse.ListController.FILTERS, function(filter) {
Discourse["List" + filter.capitalize() + "Route"] = Discourse.FilteredListRoute.extend({ filter: filter });
});
_.each(Discourse.TopList.PERIODS, function(period) {
Discourse["ListTop" + period.capitalize() + "Route"] = Discourse.FilteredListRoute.extend({ filter: "top/" + period });
});

View File

@ -1,50 +0,0 @@
/**
The route for listing categories.
@class ListCategoriesRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.ListCategoriesRoute = Discourse.Route.extend({
model: function() {
this.controllerFor('listTop').set('content', null);
this.controllerFor('listTopics').set('content', null);
return this.controllerFor('list').load('categories');
},
activate: function() {
this._super();
this.controllerFor('list').setProperties({ filterMode: 'categories', category: null });
},
redirect: function() { Discourse.redirectIfLoginRequired(this); },
afterModel: function(categoryList) {
this.controllerFor('list').setProperties({
canCreateCategory: categoryList.get('can_create_category'),
canCreateTopic: categoryList.get('can_create_topic')
});
},
renderTemplate: function() {
this.render('listCategories', { into: 'list', outlet: 'listView' });
},
deactivate: function() {
this._super();
this.controllerFor('list').set('canCreateCategory', false);
},
actions: {
createCategory: function() {
Discourse.Route.showModal(this, 'editCategory', Discourse.Category.create({
color: 'AB9364', text_color: 'FFFFFF', hotness: 5, group_permissions: [{group_name: 'everyone', permission_type: 1}],
available_groups: Discourse.Site.current().group_names
}));
this.controllerFor('editCategory').set('selectedTab', 'general');
}
},
});

View File

@ -1,74 +0,0 @@
/**
This route is used when listing a particular category's topics
@class ListCategoryRoute
@extends Discourse.Route
@namespace Discourse
@module Discourse
**/
Discourse.ListCategoryRoute = Discourse.FilteredListRoute.extend({
model: function(params) {
this.controllerFor('listTop').set('content', null);
this.controllerFor('listCategories').set('content', null);
return Discourse.Category.findBySlug(params.slug, params.parentSlug);
},
activate: function() {
this._super();
// Add a search context
this.controllerFor('search').set('searchContext', this.modelFor(this.get('routeName')).get('searchContext'));
},
setupController: function(controller, category) {
var listTopicsController = this.controllerFor('listTopics');
if (listTopicsController) {
var listContent = listTopicsController.get('content');
if (listContent) {
listContent.set('loaded', false);
}
}
var listController = this.controllerFor('list'),
categorySlug = Discourse.Category.slugFor(category),
self = this,
filter = this.get('filter') || "latest",
url = "category/" + categorySlug + "/l/" + filter,
params = {};
if (this.get('noSubcategories')) {
params.no_subcategories = true;
}
listController.setProperties({ filterMode: url, category: null });
listController.load(url, params).then(function(topicList) {
listController.setProperties({
canCreateTopic: topicList.get('can_create_topic'),
category: category
});
self.controllerFor('listTopics').setProperties({
content: topicList,
category: category
});
Discourse.FilteredListRoute.scrollToLastPosition();
});
},
deactivate: function() {
this._super();
// Clear the search context
this.controllerFor('search').set('searchContext', null);
}
});
Discourse.ListCategoryNoneRoute = Discourse.ListCategoryRoute.extend({ noSubcategories: true });
_.each(Discourse.ListController.FILTERS, function(filter) {
Discourse["List" + filter.capitalize() + "CategoryRoute"] = Discourse.ListCategoryRoute.extend({ filter: filter });
Discourse["List" + filter.capitalize() + "CategoryNoneRoute"] = Discourse.ListCategoryRoute.extend({ filter: filter, noSubcategories: true });
});
_.each(Discourse.TopList.PERIODS, function(period) {
Discourse["ListTop" + period.capitalize() + "CategoryRoute"] = Discourse.ListCategoryRoute.extend({ filter: "top/" + period });
Discourse["ListTop" + period.capitalize() + "CategoryNoneRoute"] = Discourse.ListCategoryRoute.extend({ filter: "top/" + period, noSubcategories: true });
});

View File

@ -1,42 +0,0 @@
Discourse.ListTopRoute = Discourse.Route.extend({
model: function(params) {
this.controllerFor('listCategories').set('content', null);
this.controllerFor('listTopics').set('content', null);
this.controllerFor('list').set('loading', true);
var category = Discourse.Category.findBySlug(params.slug, params.parentSlug);
if (category) { this.set('category', category); }
return Discourse.TopList.find(this.period, category);
},
activate: function() {
this._super();
this.controllerFor('list').setProperties({ filterMode: 'top', category: null });
},
redirect: function() { Discourse.redirectIfLoginRequired(this); },
setupController: function(controller, model) {
var category = this.get('category'),
categorySlug = Discourse.Category.slugFor(category),
url = category === undefined ? 'top' : 'category/' + categorySlug + '/l/top';
this.controllerFor('listTop').setProperties({ content: model, category: category });
this.controllerFor('list').setProperties({ loading: false, filterMode: url });
if (category !== undefined) {
this.controllerFor('list').set('category', category);
}
Discourse.set('title', I18n.t('filters.top.title'));
},
renderTemplate: function() {
this.render('listTop', { into: 'list', outlet: 'listView' });
}
});
Discourse.ListTopCategoryRoute = Discourse.ListTopRoute.extend({});

View File

@ -23,7 +23,7 @@
</tr>
{{#groupedEach topic in topics}}
<tr {{bindAttr class="archived"}}>
<tr {{bind-attr class="archived"}}>
<td class='main-link'>
{{topicStatus topic=topic}}
<a class='title' href="{{unbound topic.lastUnreadUrl}}">{{{unbound topic.fancy_title}}}</a>
@ -50,7 +50,7 @@
{{/if}}
</td>
<td {{bindAttr class=":num :views topic.viewsHeat"}}>{{number topic.views numberKey="views_long"}}</td>
<td {{bind-attr class=":num :views topic.viewsHeat"}}>{{number topic.views numberKey="views_long"}}</td>
{{#if topic.bumped}}
<td class='num activity'>
<a href="{{unbound topic.url}}" {{{bindAttr class=":age topic.ageCold"}}} title='{{i18n first_post}}: {{{rawDate topic.created_at}}}' >{{unboundAge topic.created_at}}</a>

View File

@ -8,4 +8,4 @@
</li>
{{/if}}
<div class='clear'></div>
<div class='clear'></div>

View File

@ -1,20 +1,19 @@
{{#if category}}
<a href="#" {{action expand}} class="badge-category" {{bindAttr style="badgeStyle"}}>{{category.name}}</a>
<a href="#" {{action expand}} class="badge-category" {{bind-attr style="badgeStyle"}}>{{category.name}}</a>
{{else}}
{{#if noSubcategories}}
<a href='#' {{action expand}} class='badge-category home' {{bindAttr style="badgeStyle"}}>{{i18n categories.no_subcategory}}</i></a>
<a href='#' {{action expand}} class='badge-category home' {{bind-attr style="badgeStyle"}}>{{i18n categories.no_subcategory}}</i></a>
{{else}}
<a href='#' {{action expand}} class='badge-category home' {{bindAttr style="badgeStyle"}}>{{allCategoriesLabel}}</i></a>
<a href='#' {{action expand}} class='badge-category home' {{bind-attr style="badgeStyle"}}>{{allCategoriesLabel}}</i></a>
{{/if}}
{{/if}}
{{#if categories}}
<a href='#' {{action expand}} class='badge-category category-dropdown-button' {{bindAttr style="badgeStyle"}}><i {{bindAttr class="iconClass"}}></i></a>
<section {{bindAttr class="expanded::hidden :category-dropdown-menu"}} class='chooser'>
<div class='cat'><a {{bindAttr href=allCategoriesUrl}} class='badge-category home'>{{allCategoriesLabel}}</a></div>
<a href='#' {{action expand}} class='badge-category category-dropdown-button' {{bind-attr style="badgeStyle"}}><i {{bind-attr class="iconClass"}}></i></a>
<section {{bind-attr class="expanded::hidden :category-dropdown-menu"}} class='chooser'>
<div class='cat'><a {{bind-attr href=allCategoriesUrl}} data-drop-close="true" class='badge-category home'>{{allCategoriesLabel}}</a></div>
{{#if subCategory}}
<div class='cat'><a {{bindAttr href=noCategoriesUrl}} class='badge-category home'>{{i18n categories.no_subcategory}}</a></div>
<div class='cat'><a {{bind-attr href=noCategoriesUrl}} data-drop-close="true" class='badge-category home'>{{i18n categories.no_subcategory}}</a></div>
{{/if}}
{{#each categories}}<div class='cat'>{{categoryLink this allowUncategorized=true}}</div>{{/each}}
</section>

View File

@ -1,4 +1,4 @@
<b>{{i18n admin.logs.screened_ips.form.label}}</b>
{{textField value=ip_address disabled=formSubmitted class="ip-address-input" placeholderKey="admin.logs.screened_ips.form.ip_address" autocorrect="off" autocapitalize="off"}}
{{combobox content=actionNames value=actionName}}
<button class="btn btn-small" {{action submit target="view"}} {{bindAttr disabled="formSubmitted"}}>{{i18n admin.logs.screened_ips.form.add}}</button>
<button class="btn btn-small" {{action submit target="view"}} {{bind-attr disabled="formSubmitted"}}>{{i18n admin.logs.screened_ips.form.add}}</button>

View File

@ -1,2 +1,2 @@
{{yield}}
<i {{bindAttr class="iconSortClass"}}></i>
<i {{bind-attr class="iconSortClass"}}></i>

View File

@ -1,3 +0,0 @@
<div {{bindAttr class=":contents :loading loading::hidden"}}>
<div class='spinner'>{{i18n loading}}</div>
</div>

View File

@ -1,20 +1,20 @@
<nav class='buttons'>
<button class='btn' {{action toggleMap}} title="{{i18n topic.toggle_information}}">
<i {{bindAttr class=":fa toggleMapClass"}}></i>
<i {{bind-attr class=":fa toggleMapClass"}}></i>
</button>
</nav>
<section {{bindAttr class=":map mapCollapsed"}}>
<section {{bind-attr class=":map mapCollapsed"}}>
<ul class="clearfix">
<li>
<a href='{{unbound topic.url}}' {{bindAttr class=topic.ageCold}}>
<a href='{{unbound topic.url}}' {{bind-attr class=topic.ageCold}}>
<h4>{{i18n created}}</h4>
{{avatar details.created_by imageSize="tiny"}}
{{unboundDate topic.created_at}}
</a>
</li>
<li>
<a {{bindAttr href="topic.lastPostUrl"}}>
<a {{bind-attr href="topic.lastPostUrl"}}>
<h4>{{i18n last_post}}</h4>
{{avatar details.last_poster imageSize="tiny"}}
{{unboundDate topic.last_posted_at}}
@ -44,7 +44,7 @@
{{number details.links.length}}
</li>
{{/if}}
<li {{bindAttr class=":avatars mapCollapsed::hidden"}}>
<li {{bind-attr class=":avatars mapCollapsed::hidden"}}>
{{#groupedEach participant in details.fewParticipants}}{{topic-participant participant=participant}}{{/groupedEach}}
</li>
</ul>

View File

@ -1,4 +1,4 @@
<a href='#' {{bindAttr class=":poster toggled"}} {{action toggle}} title="{{unbound participant.username}}">
<a href='#' {{bind-attr class=":poster toggled"}} {{action toggle}} title="{{unbound participant.username}}">
<span class='post-count'>{{unbound participant.post_count}}</span>
{{avatar participant imageSize="medium"}}
</a>
</a>

View File

@ -67,7 +67,7 @@
{{popupInputTip validation=view.replyValidation shownAt=view.showReplyTip}}
</div>
<div class='preview-wrapper'>
<div id='wmd-preview' {{bindAttr class="hidePreview:hidden"}}></div>
<div id='wmd-preview' {{bind-attr class="hidePreview:hidden"}}></div>
</div>
{{#if currentUser}}
<a href="#" {{action togglePreview}} class='toggle-preview'>{{{model.toggleText}}}</a>
@ -82,7 +82,7 @@
{{#if currentUser}}
<div class='submit-panel'>
<button {{action save}} tabindex="4" {{bindAttr class=":btn :btn-primary :create model.cantSubmitPost:disabled"}}>{{model.saveText}}</button>
<button {{action save}} tabindex="4" {{bind-attr class=":btn :btn-primary :create model.cantSubmitPost:disabled"}}>{{model.saveText}}</button>
<a href='#' {{action cancel}} class='cancel' tabindex="4">{{i18n cancel}}</a>
</div>
{{/if}}

View File

@ -1,2 +1,2 @@
<a href='#' {{action closeMessage this}} class='close'><i class='fa fa-times-circle'></i></a>
{{{body}}}
{{{body}}}

View File

@ -0,0 +1,22 @@
{{customHTML "top"}}
<div class='list-controls'>
<div class="container">
{{outlet navigation-bar}}
</div>
</div>
<div {{bind-attr class="loading::hidden"}}>
<div class='spinner'>{{i18n loading}}</div>
</div>
<div {{bind-attr class=":container :list-container loading:hidden"}}>
<div class="row">
<div class="full-width">
<div id='list-area'>
{{outlet list-container}}
</div>
</div>
</div>
</div>

View File

@ -13,7 +13,7 @@
</thead>
<tbody>
{{#each model.categories}}
<tr data-category_id='{{unbound id}}' {{bindAttr class="description_excerpt:has-description:no-description"}}>
<tr data-category_id='{{unbound id}}' {{bind-attr class="description_excerpt:has-description:no-description"}}>
<td class='category'>
<div>
<div class="pull-left">
@ -47,7 +47,7 @@
</div>
{{/if}}
</td>
<td {{bindAttr class="archived :latest"}}>
<td {{bind-attr class="archived :latest"}}>
{{#each featuredTopics}}
<div class="featured-topic">
{{topicStatus topic=this}}
@ -74,7 +74,7 @@
</div>
{{/each}}
</td>
<td class='stats' {{bindAttr title="topicStatsTitle"}}>
<td class='stats' {{bind-attr title="topicStatsTitle"}}>
<table class="categoryStats">
{{#each topicCountStats}}
<tr>
@ -84,7 +84,7 @@
{{/each}}
</table>
</td>
<td class='stats' {{bindAttr title="postStatsTitle"}}>
<td class='stats' {{bind-attr title="postStatsTitle"}}>
<table class="categoryStats">
{{#each postCountStats}}
<tr>

View File

@ -0,0 +1,48 @@
<div class="top-lists">
{{#if redirectedToTopPageReason}}
<div class="alert alert-info">
{{redirectedToTopPageReason}}
</div>
{{/if}}
{{#if content.yearly}}
<div class="clearfix">
<h2>{{i18n filters.top.this_year}}</h2>
{{basic-topic-list topicList=content.yearly}}
{{#if content.yearly.topics.length}}<a href="{{unbound showMoreYearlyUrl}}" class='btn pull-right'>{{i18n show_more}}</a>{{/if}}
</div>
{{/if}}
{{#if content.monthly}}
<div class="clearfix">
<h2>{{i18n filters.top.this_month}}</h2>
{{basic-topic-list topicList=content.monthly}}
{{#if content.monthly.topics.length}}<a href="{{unbound showMoreMonthlyUrl}}" class='btn pull-right'>{{i18n show_more}}</a>{{/if}}
</div>
{{/if}}
{{#if content.weekly}}
<div class="clearfix">
<h2>{{i18n filters.top.this_week}}</h2>
{{basic-topic-list topicList=content.weekly}}
{{#if content.weekly.topics.length}}<a href="{{unbound showMoreWeeklyUrl}}" class='btn pull-right'>{{i18n show_more}}</a>{{/if}}
</div>
{{/if}}
{{#if content.daily}}
<div class="clearfix">
<h2>{{i18n filters.top.today}}</h2>
{{basic-topic-list topicList=content.daily}}
{{#if content.daily.topics.length}}<a href="{{unbound showMoreDailyUrl}}" class='btn pull-right'>{{i18n show_more}}</a>{{/if}}
</div>
{{/if}}
<footer id="topic-list-bottom">
<h3>
{{#if hasDisplayedAllTopLists}}
{{#link-to "discovery.categories"}}{{i18n topic.browse_all_categories}}{{/link-to}} {{i18n or}} {{#link-to 'discovery.latest'}}{{i18n topic.view_latest_topics}}{{/link-to}}.
{{else}}
{{#link-to "discovery.categories"}}{{i18n topic.browse_all_categories}}{{/link-to}}, {{#link-to 'discovery.latest'}}{{i18n topic.view_latest_topics}}{{/link-to}} {{i18n or}} {{i18n filters.top.other_periods}}
{{#unless content.yearly}}<a href="{{unbound showMoreYearlyUrl}}" class='btn'>{{i18n filters.top.this_year}}</a>{{/unless}}
{{#unless content.monthly}}<a href="{{unbound showMoreMonthlyUrl}}" class='btn'>{{i18n filters.top.this_month}}</a>{{/unless}}
{{#unless content.weekly}}<a href="{{unbound showMoreWeeklyUrl}}" class='btn'>{{i18n filters.top.this_week}}</a>{{/unless}}
{{#unless content.daily}}<a href="{{unbound showMoreDailyUrl}}" class='btn'>{{i18n filters.top.today}}</a>{{/unless}}
{{/if}}
</h3>
</footer>
</div>

View File

@ -0,0 +1,70 @@
<div class='contents'>
{{#if showTable}}
<table id='topic-list'>
<thead>
<tr>
{{#if currentUser}}
<th>&nbsp;</th>
{{/if}}
{{#sortable-heading sortBy="default" sortOrder=sortOrder}}
{{i18n topic.title}}
{{/sortable-heading}}
{{#unless category}}
{{#sortable-heading sortBy="category" sortOrder=sortOrder}}
{{i18n category_title}}
{{/sortable-heading}}
{{/unless}}
{{#sortable-heading sortBy="posters" sortOrder=sortOrder}}
{{i18n users}}
{{/sortable-heading}}
{{#sortable-heading sortBy="posts" number=true sortOrder=sortOrder}}
{{i18n posts}}
{{/sortable-heading}}
{{#sortable-heading sortBy="likes" number=true sortOrder=sortOrder}}
{{i18n likes}}
{{/sortable-heading}}
{{#sortable-heading sortBy="views" number=true sortOrder=sortOrder}}
{{i18n views}}
{{/sortable-heading}}
{{#sortable-heading sortBy="activity" number=true colspan="2" sortOrder=sortOrder}}
{{i18n activity}}
{{/sortable-heading}}
</tr>
</thead>
{{#if topicTrackingState.hasIncoming}}
<tbody>
<tr>
<td colspan="9">
<div class='alert alert-info clickable' {{action showInserted}}>
{{countI18n new_topics_inserted count=topicTrackingState.incomingCount}}
{{i18n show_new_topics}}
</div>
</td>
</tr>
</tbody>
{{/if}}
{{collection contentBinding="topics" tagName="tbody" itemViewClass="Discourse.TopicListItemView"}}
</table>
{{/if}}
</div>
<footer id='topic-list-bottom'>
{{#if loadingMore}}
<div class='topics-loading'>{{i18n topic.loading_more}}</div>
{{/if}}
<h3>
{{footerMessage}}
{{#if allLoaded}}
{{#if latest}}
{{#if canCreateTopic}}
<a href='#' {{action createTopic}}>{{i18n topic.suggest_create_topic}}</a>
{{/if}}
{{else}}
{{#link-to "discovery.categories"}}{{i18n topic.browse_all_categories}}{{/link-to}} {{i18n or}} {{#link-to 'discovery.latest'}}{{i18n topic.view_latest_topics}}{{/link-to}}
{{/if}}
{{/if}}
</h3>
</footer>

View File

@ -4,7 +4,7 @@
<div>
<a href='/users/{{unbound username}}'>{{avatar this imageSize="large"}}</a>
</div>
<h5 {{bindAttr class="staff new_user"}}><a href='{{unbound usernameUrl}}'>{{{breakUp username name}}}</a></h5>
<h5 {{bind-attr class="staff new_user"}}><a href='{{unbound usernameUrl}}'>{{{breakUp username name}}}</a></h5>
</div>
</div>
<div class='span11 topic-body'>

View File

@ -22,7 +22,7 @@
{{/if}}
{{#each topics}}
<tr {{bindAttr class="archived"}}>
<tr {{bind-attr class="archived"}}>
<td class='main-link'>
<div class='topic-inset'>
{{topicStatus topic=this}}

View File

@ -7,7 +7,7 @@
<div class="extra-info-wrapper">
<div class="extra-info">
{{#if showStarButton}}
<a {{bindAttr class=":star topic.starred:starred"}} {{action toggleStar}} href='#' {{bindAttr title="topic.starTooltip"}}></a>
<a {{bind-attr class=":star topic.starred:starred"}} {{action toggleStar}} href='#' {{bind-attr title="topic.starTooltip"}}></a>
{{/if}}
<h1>
{{boundCategoryLink topic.category}}
@ -30,7 +30,7 @@
{{#unless showExtraInfo}}
<div class='current-username'>
{{#if currentUser}}
<span class='username'><a {{bindAttr href="currentUser.path"}}>{{currentUser.displayName}}</a></span>
<span class='username'><a {{bind-attr href="currentUser.path"}}>{{currentUser.displayName}}</a></span>
{{else}}
<button {{action showLogin}} class='btn btn-primary btn-small'>{{i18n log_in}}</button>
{{/if}}

View File

@ -1,38 +0,0 @@
{{customHTML "top"}}
<div class='list-controls'>
<div class="container">
{{bread-crumbs category=category categories=categories noSubcategories=noSubcategories}}
<ul class="nav nav-pills" id='category-filter'>
{{each availableNavItems itemViewClass="Discourse.NavItemView"}}
</ul>
{{#if canCreateTopic}}
<button id="create-topic" class='btn btn-default' {{action createTopic}}><i class='fa fa-plus'></i>{{i18n topic.create}}</button>
{{/if}}
{{#if canEditCategory}}
<button class='btn btn-default' {{action editCategory category}}><i class="fa fa-wrench"></i> {{i18n category.edit_long}}</button>
{{/if}}
{{#if canCreateCategory}}
<button class='btn btn-default' {{action createCategory}}><i class='fa fa-plus'></i>{{i18n category.create}}</button>
{{/if}}
</div>
</div>
<div class="container list-container">
<div class="row">
<div class="full-width">
<div id='list-area'>
{{topic-list-loading loading=loading}}
{{outlet listView}}
</div>
</div>
</div>
</div>
{{customHTML "bottom"}}

View File

@ -1,50 +0,0 @@
{{#if content}}
<div class="top-lists">
{{#if redirectedToTopPageReason}}
<div class="alert alert-info">
{{redirectedToTopPageReason}}
</div>
{{/if}}
{{#if content.yearly}}
<div class="clearfix">
<h2>{{i18n filters.top.this_year}}</h2>
{{basic-topic-list topicList=content.yearly}}
{{#if content.yearly.topics.length}}<a href={{unbound showMoreYearlyUrl}} class='btn pull-right'>{{i18n show_more}}</a>{{/if}}
</div>
{{/if}}
{{#if content.monthly}}
<div class="clearfix">
<h2>{{i18n filters.top.this_month}}</h2>
{{basic-topic-list topicList=content.monthly}}
{{#if content.monthly.topics.length}}<a href={{unbound showMoreMonthlyUrl}} class='btn pull-right'>{{i18n show_more}}</a>{{/if}}
</div>
{{/if}}
{{#if content.weekly}}
<div class="clearfix">
<h2>{{i18n filters.top.this_week}}</h2>
{{basic-topic-list topicList=content.weekly}}
{{#if content.weekly.topics.length}}<a href={{unbound showMoreWeeklyUrl}} class='btn pull-right'>{{i18n show_more}}</a>{{/if}}
</div>
{{/if}}
{{#if content.daily}}
<div class="clearfix">
<h2>{{i18n filters.top.today}}</h2>
{{basic-topic-list topicList=content.daily}}
{{#if content.daily.topics.length}}<a href={{unbound showMoreDailyUrl}} class='btn pull-right'>{{i18n show_more}}</a>{{/if}}
</div>
{{/if}}
<footer id="topic-list-bottom">
<h3>
{{#if hasDisplayedAllTopLists}}
{{#link-to "list.categories"}}{{i18n topic.browse_all_categories}}{{/link-to}} {{i18n or}} {{#link-to 'list.latest'}}{{i18n topic.view_latest_topics}}{{/link-to}}.
{{else}}
{{#link-to "list.categories"}}{{i18n topic.browse_all_categories}}{{/link-to}}, {{#link-to 'list.latest'}}{{i18n topic.view_latest_topics}}{{/link-to}} {{i18n or}} {{i18n filters.top.other_periods}}
{{#unless content.yearly}}<a href={{unbound showMoreYearlyUrl}} class='btn'>{{i18n filters.top.this_year}}</a>{{/unless}}
{{#unless content.monthly}}<a href={{unbound showMoreMonthlyUrl}} class='btn'>{{i18n filters.top.this_month}}</a>{{/unless}}
{{#unless content.weekly}}<a href={{unbound showMoreWeeklyUrl}} class='btn'>{{i18n filters.top.this_week}}</a>{{/unless}}
{{#unless content.daily}}<a href={{unbound showMoreDailyUrl}} class='btn'>{{i18n filters.top.today}}</a>{{/unless}}
{{/if}}
</h3>
</footer>
</div>
{{/if}}

View File

@ -1,21 +1,10 @@
{{#if controller.currentUser.id}}
<td class='star'>
<a {{bindAttr class=":star :fa :fa-star starred:starred"}} {{action toggleStar this}} href='#' {{bindAttr title="starTooltip"}}></a>
<a {{bind-attr class=":star :fa :fa-star starred:starred"}} {{action toggleStar this}} href='#' {{bind-attr title="starTooltip"}}></a>
</td>
{{/if}}
<td class='main-link clearfix'>
{{#if controller.rankDetailsVisible}}
<div class='rank-details'>
<p>{{rank_details.hot_topic_type}}</p>
<p>
({{float rank_details.random_bias}} * {{float rank_details.random_multiplier}}) + ({{float rank_details.days_ago_bias}} * {{float rank_details.days_ago_multiplier}}) = <b>{{float rank_details.ranking_score}}</b>
<i class='fa fa-flask score' {{action showRankDetails this}} title='{{i18n rank_details.show}}'></i>
</p>
</div>
{{/if}}
{{topicStatus topic=this}}
{{{topicLink this}}}
{{#if unread}}
@ -41,7 +30,7 @@
{{/if}}
</td>
{{#unless controller.category}}
{{#unless controller.hideCategory}}
<td class='category'>
{{categoryLink category}}
</td>
@ -61,7 +50,7 @@
{{/if}}
</td>
<td {{bindAttr class=":num :views viewsHeat"}}>{{number views numberKey="views_long"}}</td>
<td {{bind-attr class=":num :views viewsHeat"}}>{{number views numberKey="views_long"}}</td>
{{#if bumped}}
<td class='num activity'>

View File

@ -1,85 +0,0 @@
{{topic-list-loading loading=topicListReloading}}
{{#unless loading}}
{{#if loaded}}
<div class='contents'>
{{#if view.showTable}}
{{#if canViewRankDetails}}
<button class='btn' {{action toggleRankDetails}} style='margin-bottom: 10px'>
<i class='fa fa-flask'></i>
{{i18n rank_details.toggle}}
</button>
{{/if}}
<table id='topic-list'>
<thead>
<tr>
{{#if currentUser}}
<th>&nbsp;</th>
{{/if}}
{{#sortable-heading sortBy="default" sortOrder=sortOrder}}
{{i18n topic.title}}
{{/sortable-heading}}
{{#unless category}}
{{#sortable-heading sortBy="category" sortOrder=sortOrder}}
{{i18n category_title}}
{{/sortable-heading}}
{{/unless}}
{{#sortable-heading sortBy="posters" sortOrder=sortOrder}}
{{i18n users}}
{{/sortable-heading}}
{{#sortable-heading sortBy="posts" number=true sortOrder=sortOrder}}
{{i18n posts}}
{{/sortable-heading}}
{{#sortable-heading sortBy="likes" number=true sortOrder=sortOrder}}
{{i18n likes}}
{{/sortable-heading}}
{{#sortable-heading sortBy="views" number=true sortOrder=sortOrder}}
{{i18n views}}
{{/sortable-heading}}
{{#sortable-heading sortBy="activity" number=true colspan="2" sortOrder=sortOrder}}
{{i18n activity}}
{{/sortable-heading}}
</tr>
</thead>
{{#if view.topicTrackingState.hasIncoming}}
<tbody>
<tr>
<td colspan="9">
<div class='alert alert-info clickable' {{action showInserted}}>
{{countI18n new_topics_inserted countBinding="view.topicTrackingState.incomingCount"}}
{{i18n show_new_topics}}
</div>
</td>
</tr>
</tbody>
{{/if}}
{{collection contentBinding="topics" tagName="tbody" itemViewClass="Discourse.TopicListItemView"}}
</table>
{{/if}}
</div>
<footer id='topic-list-bottom'>
{{#if loadingMore}}
<div class='topics-loading'>{{i18n topic.loading_more}}</div>
{{/if}}
<h3>
{{footerMessage}}
{{#if allLoaded}}
{{#if latest}}
{{#if canCreateTopic}}
<a href='#' {{action createTopic}}>{{i18n topic.suggest_create_topic}}</a>
{{/if}}
{{else}}
{{#link-to "list.categories"}}{{i18n topic.browse_all_categories}}{{/link-to}} {{i18n or}} {{#link-to 'list.latest'}}{{i18n topic.view_latest_topics}}{{/link-to}}
{{/if}}
{{/if}}
</h3>
</footer>
{{/if}}
{{/unless}}

View File

@ -2,7 +2,7 @@
{{#if topics}}
<table id="topic-list">
{{#groupedEach topic in topics}}
<tr {{bindAttr class="archived"}}>
<tr {{bind-attr class="archived"}}>
<td>
<div class='main-link clearfix'>
{{topicStatus topic=this}}
@ -43,7 +43,7 @@
</a>
</div>
{{/if}}
<div {{bindAttr class=":num :views viewsHeat"}}>
<div {{bind-attr class=":num :views viewsHeat"}}>
<a href="{{lastUnreadUrl}}">
<i class='fa fa-eye'></i> {{number views numberKey="views_long"}}
</a>

View File

@ -1 +1 @@
{{each categories itemViewClass="Discourse.FeaturedTopicsView"}}
{{each categories itemViewClass="Discourse.FeaturedTopicsView"}}

View File

@ -1,16 +1,5 @@
<td>
<div class='main-link clearfix'>
{{#if controller.rankDetailsVisible}}
<div class='rank-details'>
<p>{{rank_details.hot_topic_type}}</p>
<p>
({{float rank_details.random_bias}} * {{float rank_details.random_multiplier}}) + ({{float rank_details.days_ago_bias}} * {{float rank_details.days_ago_multiplier}}) = <b>{{float rank_details.ranking_score}}</b>
<i class='fa fa-flask score' {{action showRankDetails this}} title='{{i18n rank_details.show}}'></i>
</p>
</div>
{{/if}}
{{topicStatus topic=this}}
{{{topicLink this}}}
{{#if unread}}
@ -64,4 +53,4 @@
</div>
<div class="clearfix"></div>
</div>
</td>
</td>

View File

@ -2,13 +2,6 @@
{{#if loaded}}
<div class='contents'>
{{#if view.showTable}}
{{#if canViewRankDetails}}
<button class='btn' {{action toggleRankDetails}} style='margin-bottom: 10px'>
<i class='fa fa-flask'></i>
{{i18n rank_details.toggle}}
</button>
{{/if}}
<table id='topic-list'>
{{#if view.topicTrackingState.hasIncoming}}
@ -43,7 +36,7 @@
<a href='#' {{action createTopic}}>{{i18n topic.suggest_create_topic}}</a>
{{/if}}
{{else}}
{{#link-to 'list.categories'}}{{i18n topic.browse_all_categories}}{{/link-to}} {{i18n or}} {{#link-to 'list.latest'}}{{i18n topic.view_latest_topics}}{{/link-to}}
{{#link-to 'discovery.categories'}}{{i18n topic.browse_all_categories}}{{/link-to}} {{i18n or}} {{#link-to 'discovery.latest'}}{{i18n topic.view_latest_topics}}{{/link-to}}
{{/if}}
{{/if}}
</h3>

View File

@ -41,7 +41,7 @@
</form>
{{/if}}
{{authMessage}}
<div id='login-alert' {{bindAttr class="alertClass"}}>{{alert}}</div>
<div id='login-alert' {{bind-attr class="alertClass"}}>{{alert}}</div>
</div>
<div class="modal-footer">
{{#if authenticate}}
@ -49,7 +49,7 @@
{{/if}}
{{#if Discourse.SiteSettings.enable_local_logins}}
<button class='btn btn-large btn-primary'
{{bindAttr disabled="loginDisabled"}}
{{bind-attr disabled="loginDisabled"}}
{{action login}}>
<i class="fa fa-unlock"></i>&nbsp;{{loginButtonText}}
</button>

View File

@ -5,4 +5,4 @@
</div>
<div class="modal-footer">
<button class='btn btn-primary' {{action closeModal}}>{{i18n post.archetypes.save}}</button>
</div>
</div>

View File

@ -3,7 +3,7 @@
{{auto-close-form autoCloseTime=auto_close_time autoCloseValid=auto_close_valid}}
</div>
<div class="modal-footer">
<button class='btn btn-primary' type='submit' {{bindAttr disabled="auto_close_invalid"}}>{{i18n topic.auto_close_save}}</button>
<button class='btn btn-primary' type='submit' {{bind-attr disabled="auto_close_invalid"}}>{{i18n topic.auto_close_save}}</button>
<a {{action closeModal}}>{{i18n cancel}}</a>
<button class='btn pull-right' {{action removeAutoClose}}>{{i18n topic.auto_close_remove}}</button>
</div>

View File

@ -14,7 +14,7 @@
{{i18n user.change_avatar.uploaded_avatar_empty}}
{{/if}}
</label>
<button id="fake-avatar-input" class="btn" {{bindAttr disabled="view.uploading"}} title="{{i18n user.change_avatar.upload_title}}">
<button id="fake-avatar-input" class="btn" {{bind-attr disabled="view.uploading"}} title="{{i18n user.change_avatar.upload_title}}">
<i class="fa fa-picture-o"></i>&nbsp;{{view.uploadButtonText}}
</button>
<input type="file" id="avatar-input" accept="image/*" style="display:none">
@ -29,6 +29,6 @@
</div>
<div class="modal-footer">
<button class="btn btn-primary" {{action saveAvatarSelection}} {{bindAttr disabled="view.saveDisabled"}}>{{i18n save}}</button>
<button class="btn btn-primary" {{action saveAvatarSelection}} {{bind-attr disabled="view.saveDisabled"}}>{{i18n save}}</button>
<a {{action closeModal}}>{{i18n cancel}}</a>
</div>

View File

@ -67,11 +67,11 @@
</div>
<div class="modal-footer">
<button class='btn btn-large btn-primary' {{bindAttr disabled="submitDisabled"}} {{action createAccount}}>{{i18n create_account.title}}</button>
<button class='btn btn-large btn-primary' {{bind-attr disabled="submitDisabled"}} {{action createAccount}}>{{i18n create_account.title}}</button>
{{#if formSubmitted}}
&nbsp; <i class='fa fa-spinner fa-spin'></i>
{{else}}
&nbsp; <a {{action showLogin}}>{{i18n cancel}}</a>
{{/if}}
</div>
{{/unless}}
{{/unless}}

View File

@ -1,20 +1,20 @@
<div {{bindAttr class="loading:invisible"}}>
<div {{bind-attr class="loading:invisible"}}>
<ul class="nav nav-pills">
<li {{bindAttr class="generalSelected:active"}}>
<li {{bind-attr class="generalSelected:active"}}>
<a href="#" {{action selectGeneral}}>{{i18n category.general}}</a>
</li>
{{#unless isUncategorized}}
<li {{bindAttr class="securitySelected:active"}}>
<li {{bind-attr class="securitySelected:active"}}>
<a href="#" {{action selectSecurity}}>{{i18n category.security}}</a>
</li>
<li {{bindAttr class="settingsSelected:active"}}>
<li {{bind-attr class="settingsSelected:active"}}>
<a href="#" {{action selectSettings}}>{{i18n category.settings}}</a>
</li>
{{/unless}}
</ul>
<div class="modal-body">
<div {{bindAttr class=":modal-tab :general-tab generalSelected::invisible"}}>
<div {{bind-attr class=":modal-tab :general-tab generalSelected::invisible"}}>
<form>
<section class='field'>
<label>{{i18n category.name}}</label>
@ -45,7 +45,7 @@
<section class='field'>
<label>{{i18n category.badge_colors}}</label>
<div class="category-color-editor">
<span class='badge-category' {{bindAttr style="colorStyle"}}>{{categoryName}}</span>
<span class='badge-category' {{bind-attr style="colorStyle"}}>{{categoryName}}</span>
<div class='input-prepend input-append' style="margin-top: 10px;">
<span class='color-title'>{{i18n category.background_color}}:</span>
@ -63,7 +63,7 @@
</form>
</div>
{{#unless isUncategorized}}
<div {{bindAttr class=":modal-tab :options-tab securitySelected::invisible"}}>
<div {{bind-attr class=":modal-tab :options-tab securitySelected::invisible"}}>
<section class='field'>
<ul class='permission-list'>
{{#each permissions}}
@ -86,7 +86,7 @@
{{/if}}
</section>
</div>
<div {{bindAttr class=":modal-tab :options-tab settingsSelected::invisible"}}>
<div {{bind-attr class=":modal-tab :options-tab settingsSelected::invisible"}}>
<section class='field'>
<div class="auto-close-fields">
<div>
@ -102,8 +102,8 @@
<label>{{i18n category.position}}</label>
<span {{action disableDefaultPosition}}>{{textField value=position disabled=defaultPosition class="position-input"}}</span>
&nbsp;{{i18n or}}&nbsp;
<button {{bindAttr class=":btn defaultPosition:btn-primary"}} {{action toggleDefaultPosition}}>
<span {{bindAttr class="defaultPosition::hidden"}}><i class="fa fa-check"></i></span>
<button {{bind-attr class=":btn defaultPosition:btn-primary"}} {{action toggleDefaultPosition}}>
<span {{bind-attr class="defaultPosition::hidden"}}><i class="fa fa-check"></i></span>
{{i18n category.default_position}}
</button>
</section>
@ -116,9 +116,9 @@
{{/unless}}
</div>
<div class="modal-footer">
<button class='btn btn-primary' {{bindAttr disabled="disabled"}} {{action saveCategory}}>{{buttonTitle}}</button>
<button class='btn btn-primary' {{bind-attr disabled="disabled"}} {{action saveCategory}}>{{buttonTitle}}</button>
{{#if deleteVisible}}
<button class='btn btn-danger pull-right' {{bindAttr disabled="deleteDisabled"}} {{action deleteCategory}}><i class="fa fa-trash-o"></i>{{deleteButtonTitle}}</button>
<button class='btn btn-danger pull-right' {{bind-attr disabled="deleteDisabled"}} {{action deleteCategory}}><i class="fa fa-trash-o"></i>{{deleteButtonTitle}}</button>
{{/if}}
</div>
</div>

View File

@ -11,7 +11,7 @@
</label>
{{#if showMessageInput}}
{{textarea name="message" class="flag-message" placeholder=customPlaceholder value=message}}
<div {{bindAttr class=":custom-message-length customMessageLengthClasses"}}>{{customMessageLength}}</div>
<div {{bind-attr class=":custom-message-length customMessageLengthClasses"}}>{{customMessageLength}}</div>
{{/if}}
</div>
{{else}}
@ -21,14 +21,14 @@
</div>
<div class="modal-footer">
<button class='btn btn-primary' {{action createFlag}} {{bindAttr disabled="submitDisabled"}}>{{submitText}}</button>
<button class='btn btn-primary' {{action createFlag}} {{bind-attr disabled="submitDisabled"}}>{{submitText}}</button>
{{#if canTakeAction}}
<button class='btn btn-danger' {{action takeAction}} {{bindAttr disabled="submitDisabled"}}>{{i18n flagging.take_action}}</button>
<button class='btn btn-danger' {{action takeAction}} {{bind-attr disabled="submitDisabled"}}>{{i18n flagging.take_action}}</button>
{{/if}}
{{#if canDeleteSpammer}}
<button class="btn btn-danger" {{action deleteSpammer}} {{bindAttr disabled="submitDisabled"}}><i class="fa fa-exclamation-triangle"></i> {{i18n flagging.delete_spammer}}</button>
<button class="btn btn-danger" {{action deleteSpammer}} {{bind-attr disabled="submitDisabled"}}><i class="fa fa-exclamation-triangle"></i> {{i18n flagging.delete_spammer}}</button>
{{/if}}
</div>

View File

@ -4,6 +4,6 @@
{{textField value=accountEmailOrUsername placeholderKey="login.email_placeholder" id="username-or-email" autocorrect="off" autocapitalize="off"}}
</div>
<div class="modal-footer">
<button class='btn btn-large btn-primary' {{bindAttr disabled="submitDisabled"}} {{action submit}}>{{i18n forgot_password.reset}}</button>
<button class='btn btn-large btn-primary' {{bind-attr disabled="submitDisabled"}} {{action submit}}>{{i18n forgot_password.reset}}</button>
</div>
</form>

View File

@ -4,17 +4,17 @@
{{else}}
<div>
<div id="revision-controls">
<button class="btn standard" title="{{i18n post.revisions.controls.first}}" {{action loadFirstVersion}} {{bindAttr disabled=isFirstVersion}}><i class="fa fa-fast-backward"></i></button>
<button class="btn standard" title="{{i18n post.revisions.controls.previous}}" {{action loadPreviousVersion}} {{bindAttr disabled=isFirstVersion}}><i class="fa fa-backward"></i></button>
<button class="btn standard" title="{{i18n post.revisions.controls.first}}" {{action loadFirstVersion}} {{bind-attr disabled=isFirstVersion}}><i class="fa fa-fast-backward"></i></button>
<button class="btn standard" title="{{i18n post.revisions.controls.previous}}" {{action loadPreviousVersion}} {{bind-attr disabled=isFirstVersion}}><i class="fa fa-backward"></i></button>
{{{i18n post.revisions.controls.comparing_previous_to_current_out_of_total previous=previousVersionNumber current=currentVersionNumber total=revisions_count}}}
<button class="btn standard" title="{{i18n post.revisions.controls.next}}" {{action loadNextVersion}} {{bindAttr disabled=isLastVersion}}><i class="fa fa-forward"></i></button>
<button class="btn standard" title="{{i18n post.revisions.controls.last}}" {{action loadLastVersion}} {{bindAttr disabled=isLastVersion}}><i class="fa fa-fast-forward"></i></button>
<button class="btn standard" title="{{i18n post.revisions.controls.next}}" {{action loadNextVersion}} {{bind-attr disabled=isLastVersion}}><i class="fa fa-forward"></i></button>
<button class="btn standard" title="{{i18n post.revisions.controls.last}}" {{action loadLastVersion}} {{bind-attr disabled=isLastVersion}}><i class="fa fa-fast-forward"></i></button>
</div>
<div id="display-modes">
<button {{bindAttr class=":btn displayingInline:btn-primary:standard"}} title="{{i18n post.revisions.displays.inline.title}}" {{action displayInline}}>{{{i18n post.revisions.displays.inline.button}}}</button>
<button {{bind-attr class=":btn displayingInline:btn-primary:standard"}} title="{{i18n post.revisions.displays.inline.title}}" {{action displayInline}}>{{{i18n post.revisions.displays.inline.button}}}</button>
{{#unless Discourse.Mobile.mobileView}}
<button {{bindAttr class=":btn displayingSideBySide:btn-primary:standard"}} title="{{i18n post.revisions.displays.side_by_side.title}}" {{action displaySideBySide}}>{{{i18n post.revisions.displays.side_by_side.button}}}</button>
<button {{bindAttr class=":btn displayingSideBySideMarkdown:btn-primary:standard"}} title="{{i18n post.revisions.displays.side_by_side_markdown.title}}" {{action displaySideBySideMarkdown}}>{{{i18n post.revisions.displays.side_by_side_markdown.button}}}</button>
<button {{bind-attr class=":btn displayingSideBySide:btn-primary:standard"}} title="{{i18n post.revisions.displays.side_by_side.title}}" {{action displaySideBySide}}>{{{i18n post.revisions.displays.side_by_side.button}}}</button>
<button {{bind-attr class=":btn displayingSideBySideMarkdown:btn-primary:standard"}} title="{{i18n post.revisions.displays.side_by_side_markdown.title}}" {{action displaySideBySideMarkdown}}>{{{i18n post.revisions.displays.side_by_side_markdown.button}}}</button>
{{/unless}}
</div>
</div>

View File

@ -18,7 +18,7 @@
{{#if finished}}
<button class='btn btn-primary' {{action closeModal}}>{{i18n close}}</button>
{{else}}
<button class='btn btn-primary' {{bindAttr disabled="disabled"}} {{action createInvite}}>{{buttonTitle}}</button>
<button class='btn btn-primary' {{bind-attr disabled="disabled"}} {{action createInvite}}>{{buttonTitle}}</button>
{{/if}}
</div>
</div>

View File

@ -17,7 +17,7 @@
{{#if finished}}
<button class='btn btn-primary' {{action closeModal}}>{{i18n close}}</button>
{{else}}
<button class='btn btn-primary' {{bindAttr disabled="disabled"}} {{action invite}}>{{buttonTitle}}</button>
<button class='btn btn-primary' {{bind-attr disabled="disabled"}} {{action invite}}>{{buttonTitle}}</button>
{{/if}}
</div>

View File

@ -38,12 +38,12 @@
</form>
{{/if}}
{{authMessage}}
<div id='login-alert' {{bindAttr class="alertClass"}}>{{alert}}</div>
<div id='login-alert' {{bind-attr class="alertClass"}}>{{alert}}</div>
</div>
<div class="modal-footer">
{{#if Discourse.SiteSettings.enable_local_logins}}
<button class='btn btn-large btn-primary'
{{bindAttr disabled="loginDisabled"}}
{{bind-attr disabled="loginDisabled"}}
{{action login}}>
<i class="fa fa-unlock"></i>&nbsp;{{loginButtonText}}
</button>

View File

@ -13,5 +13,5 @@
</div>
<div class="modal-footer">
<button class='btn btn-primary' {{bindAttr disabled="buttonDisabled"}} {{action movePostsToExistingTopic}}>{{buttonTitle}}</button>
</div>
<button class='btn btn-primary' {{bind-attr disabled="buttonDisabled"}} {{action movePostsToExistingTopic}}>{{buttonTitle}}</button>
</div>

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