mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-30 10:58:31 -05:00
Load fewer posts when the android platform is detected
This commit is contained in:
parent
b83c47f088
commit
2d6b15a34d
10 changed files with 28 additions and 96 deletions
|
@ -1,11 +1,3 @@
|
||||||
/**
|
|
||||||
Our data model for interacting with site settings.
|
|
||||||
|
|
||||||
@class SiteSetting
|
|
||||||
@extends Discourse.Model
|
|
||||||
@namespace Discourse
|
|
||||||
@module Discourse
|
|
||||||
**/
|
|
||||||
Discourse.SiteSetting = Discourse.Model.extend({
|
Discourse.SiteSetting = Discourse.Model.extend({
|
||||||
|
|
||||||
validationMessage: null,
|
validationMessage: null,
|
||||||
|
|
|
@ -1,59 +1,17 @@
|
||||||
/**
|
|
||||||
We use this class to keep on top of streaming and filtering posts within a topic.
|
|
||||||
|
|
||||||
@class PostStream
|
|
||||||
@extends Ember.Object
|
|
||||||
@namespace Discourse
|
|
||||||
@module Discourse
|
|
||||||
**/
|
|
||||||
Discourse.PostStream = Em.Object.extend({
|
Discourse.PostStream = Em.Object.extend({
|
||||||
|
|
||||||
/**
|
|
||||||
Are we currently loading posts in any way?
|
|
||||||
|
|
||||||
@property loading
|
|
||||||
**/
|
|
||||||
loading: Em.computed.or('loadingAbove', 'loadingBelow', 'loadingFilter', 'stagingPost'),
|
loading: Em.computed.or('loadingAbove', 'loadingBelow', 'loadingFilter', 'stagingPost'),
|
||||||
|
|
||||||
notLoading: Em.computed.not('loading'),
|
notLoading: Em.computed.not('loading'),
|
||||||
|
|
||||||
filteredPostsCount: Em.computed.alias("stream.length"),
|
filteredPostsCount: Em.computed.alias("stream.length"),
|
||||||
|
|
||||||
/**
|
hasPosts: function() {
|
||||||
Have we loaded any posts?
|
|
||||||
|
|
||||||
@property hasPosts
|
|
||||||
**/
|
|
||||||
hasPosts: function(){
|
|
||||||
return this.get('posts.length') > 0;
|
return this.get('posts.length') > 0;
|
||||||
}.property("posts.@each"),
|
}.property("posts.@each"),
|
||||||
|
|
||||||
/**
|
|
||||||
Do we have a stream list of post ids?
|
|
||||||
|
|
||||||
@property hasStream
|
|
||||||
**/
|
|
||||||
hasStream: Em.computed.gt('filteredPostsCount', 0),
|
hasStream: Em.computed.gt('filteredPostsCount', 0),
|
||||||
|
|
||||||
/**
|
|
||||||
Can we append more posts to our current stream?
|
|
||||||
|
|
||||||
@property canAppendMore
|
|
||||||
**/
|
|
||||||
canAppendMore: Em.computed.and('notLoading', 'hasPosts', 'lastPostNotLoaded'),
|
canAppendMore: Em.computed.and('notLoading', 'hasPosts', 'lastPostNotLoaded'),
|
||||||
|
|
||||||
/**
|
|
||||||
Can we prepend more posts to our current stream?
|
|
||||||
|
|
||||||
@property canPrependMore
|
|
||||||
**/
|
|
||||||
canPrependMore: Em.computed.and('notLoading', 'hasPosts', 'firstPostNotLoaded'),
|
canPrependMore: Em.computed.and('notLoading', 'hasPosts', 'firstPostNotLoaded'),
|
||||||
|
|
||||||
/**
|
|
||||||
Have we loaded the first post in the stream?
|
|
||||||
|
|
||||||
@property firstPostPresent
|
|
||||||
**/
|
|
||||||
firstPostPresent: function() {
|
firstPostPresent: function() {
|
||||||
if (!this.get('hasLoadedData')) { return false; }
|
if (!this.get('hasLoadedData')) { return false; }
|
||||||
return !!this.get('posts').findProperty('id', this.get('firstPostId'));
|
return !!this.get('posts').findProperty('id', this.get('firstPostId'));
|
||||||
|
@ -61,47 +19,22 @@ Discourse.PostStream = Em.Object.extend({
|
||||||
|
|
||||||
firstPostNotLoaded: Em.computed.not('firstPostPresent'),
|
firstPostNotLoaded: Em.computed.not('firstPostPresent'),
|
||||||
|
|
||||||
/**
|
|
||||||
The first post that we have loaded. Useful for checking to see if we should scroll upwards
|
|
||||||
|
|
||||||
@property firstLoadedPost
|
|
||||||
**/
|
|
||||||
firstLoadedPost: function() {
|
firstLoadedPost: function() {
|
||||||
return _.first(this.get('posts'));
|
return _.first(this.get('posts'));
|
||||||
}.property('posts.@each'),
|
}.property('posts.@each'),
|
||||||
|
|
||||||
/**
|
|
||||||
The last post we have loaded. Useful for checking to see if we should load more
|
|
||||||
|
|
||||||
@property lastLoadedPost
|
|
||||||
**/
|
|
||||||
lastLoadedPost: function() {
|
lastLoadedPost: function() {
|
||||||
return _.last(this.get('posts'));
|
return _.last(this.get('posts'));
|
||||||
}.property('posts.@each'),
|
}.property('posts.@each'),
|
||||||
|
|
||||||
/**
|
|
||||||
Returns the id of the first post in the set
|
|
||||||
|
|
||||||
@property firstPostId
|
|
||||||
**/
|
|
||||||
firstPostId: function() {
|
firstPostId: function() {
|
||||||
return this.get('stream')[0];
|
return this.get('stream')[0];
|
||||||
}.property('stream.@each'),
|
}.property('stream.@each'),
|
||||||
|
|
||||||
/**
|
|
||||||
Returns the id of the last post in the set
|
|
||||||
|
|
||||||
@property lastPostId
|
|
||||||
**/
|
|
||||||
lastPostId: function() {
|
lastPostId: function() {
|
||||||
return _.last(this.get('stream'));
|
return _.last(this.get('stream'));
|
||||||
}.property('stream.@each'),
|
}.property('stream.@each'),
|
||||||
|
|
||||||
/**
|
|
||||||
Have we loaded the last post in the stream?
|
|
||||||
|
|
||||||
@property loadedAllPosts
|
|
||||||
**/
|
|
||||||
loadedAllPosts: function() {
|
loadedAllPosts: function() {
|
||||||
if (!this.get('hasLoadedData')) { return false; }
|
if (!this.get('hasLoadedData')) { return false; }
|
||||||
return !!this.get('posts').findProperty('id', this.get('lastPostId'));
|
return !!this.get('posts').findProperty('id', this.get('lastPostId'));
|
||||||
|
@ -149,7 +82,7 @@ Discourse.PostStream = Em.Object.extend({
|
||||||
var firstIndex = this.indexOf(firstPost);
|
var firstIndex = this.indexOf(firstPost);
|
||||||
if (firstIndex === -1) { return []; }
|
if (firstIndex === -1) { return []; }
|
||||||
|
|
||||||
var startIndex = firstIndex - Discourse.SiteSettings.posts_chunksize;
|
var startIndex = firstIndex - this.get('topic.chunk_size');
|
||||||
if (startIndex < 0) { startIndex = 0; }
|
if (startIndex < 0) { startIndex = 0; }
|
||||||
return stream.slice(startIndex, firstIndex);
|
return stream.slice(startIndex, firstIndex);
|
||||||
|
|
||||||
|
@ -173,7 +106,7 @@ Discourse.PostStream = Em.Object.extend({
|
||||||
if ((lastIndex + 1) >= this.get('highest_post_number')) { return []; }
|
if ((lastIndex + 1) >= this.get('highest_post_number')) { return []; }
|
||||||
|
|
||||||
// find our window of posts
|
// find our window of posts
|
||||||
return stream.slice(lastIndex+1, lastIndex+Discourse.SiteSettings.posts_chunksize+1);
|
return stream.slice(lastIndex+1, lastIndex + this.get('topic.chunk_size') + 1);
|
||||||
}.property('lastLoadedPost', 'stream.@each'),
|
}.property('lastLoadedPost', 'stream.@each'),
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,3 @@
|
||||||
/**
|
|
||||||
A data model representing the site (instance of Discourse)
|
|
||||||
|
|
||||||
@class Site
|
|
||||||
@extends Discourse.Model
|
|
||||||
@namespace Discourse
|
|
||||||
@module Discourse
|
|
||||||
**/
|
|
||||||
Discourse.Site = Discourse.Model.extend({
|
Discourse.Site = Discourse.Model.extend({
|
||||||
|
|
||||||
isReadOnly: Em.computed.alias('is_readonly'),
|
isReadOnly: Em.computed.alias('is_readonly'),
|
||||||
|
|
|
@ -47,6 +47,7 @@ class TopicsController < ApplicationController
|
||||||
opts = params.slice(:username_filters, :filter, :page, :post_number, :show_deleted)
|
opts = params.slice(:username_filters, :filter, :page, :post_number, :show_deleted)
|
||||||
username_filters = opts[:username_filters]
|
username_filters = opts[:username_filters]
|
||||||
|
|
||||||
|
opts[:slow_platform] = true if request.user_agent =~ /Android/
|
||||||
opts[:username_filters] = username_filters.split(',') if username_filters.is_a?(String)
|
opts[:username_filters] = username_filters.split(',') if username_filters.is_a?(String)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
@ -58,7 +59,7 @@ class TopicsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
page = params[:page].to_i
|
page = params[:page].to_i
|
||||||
if (page < 0) || ((page - 1) * SiteSetting.posts_chunksize > @topic_view.topic.highest_post_number)
|
if (page < 0) || ((page - 1) * @topic_view.chunk_size > @topic_view.topic.highest_post_number)
|
||||||
raise Discourse::NotFound
|
raise Discourse::NotFound
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,8 @@ class TopicViewSerializer < ApplicationSerializer
|
||||||
:has_deleted,
|
:has_deleted,
|
||||||
:actions_summary,
|
:actions_summary,
|
||||||
:expandable_first_post,
|
:expandable_first_post,
|
||||||
:is_warning
|
:is_warning,
|
||||||
|
:chunk_size
|
||||||
|
|
||||||
# Define a delegator for each attribute of the topic we want
|
# Define a delegator for each attribute of the topic we want
|
||||||
attributes(*topic_attributes)
|
attributes(*topic_attributes)
|
||||||
|
@ -113,6 +113,9 @@ class TopicViewSerializer < ApplicationSerializer
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def chunk_size
|
||||||
|
object.chunk_size
|
||||||
|
end
|
||||||
|
|
||||||
def is_warning
|
def is_warning
|
||||||
object.topic.private_message? && object.topic.subtype == TopicSubtype.moderator_warning
|
object.topic.private_message? && object.topic.subtype == TopicSubtype.moderator_warning
|
||||||
|
|
|
@ -739,6 +739,7 @@ en:
|
||||||
track_external_right_clicks: "Track external links that are right clicked (eg: open in new tab) disabled by default because it rewrites URLs"
|
track_external_right_clicks: "Track external links that are right clicked (eg: open in new tab) disabled by default because it rewrites URLs"
|
||||||
topics_per_page: "How many topics are loaded by default on the topic list, and when scrolling down to load more topics"
|
topics_per_page: "How many topics are loaded by default on the topic list, and when scrolling down to load more topics"
|
||||||
posts_chunksize: "How many posts are loaded by default on a topic, and when scrolling down to load more posts"
|
posts_chunksize: "How many posts are loaded by default on a topic, and when scrolling down to load more posts"
|
||||||
|
posts_slow_chunksize: "Like `posts_chunksize` but for slow platforms (such as Android)"
|
||||||
site_contact_username: "All automated private messages will be from this user; if left blank the default System account will be used."
|
site_contact_username: "All automated private messages will be from this user; if left blank the default System account will be used."
|
||||||
send_welcome_message: "Send all new users a welcome private message with a quick start guide."
|
send_welcome_message: "Send all new users a welcome private message with a quick start guide."
|
||||||
suppress_reply_directly_below: "Don't show the expandable reply count on a post when there is only a single reply directly below this post."
|
suppress_reply_directly_below: "Don't show the expandable reply count on a post when there is only a single reply directly below this post."
|
||||||
|
|
|
@ -653,9 +653,11 @@ developer:
|
||||||
default: false
|
default: false
|
||||||
client: true
|
client: true
|
||||||
posts_chunksize:
|
posts_chunksize:
|
||||||
client: true
|
|
||||||
default: 20
|
default: 20
|
||||||
min: 1
|
min: 1
|
||||||
|
posts_slow_chunksize:
|
||||||
|
default: 10
|
||||||
|
min: 1
|
||||||
|
|
||||||
embedding:
|
embedding:
|
||||||
embeddable_host: ''
|
embeddable_host: ''
|
||||||
|
|
|
@ -5,7 +5,7 @@ require_dependency 'gaps'
|
||||||
|
|
||||||
class TopicView
|
class TopicView
|
||||||
|
|
||||||
attr_reader :topic, :posts, :guardian, :filtered_posts
|
attr_reader :topic, :posts, :guardian, :filtered_posts, :chunk_size
|
||||||
attr_accessor :draft, :draft_key, :draft_sequence, :user_custom_fields
|
attr_accessor :draft, :draft_key, :draft_sequence, :user_custom_fields
|
||||||
|
|
||||||
def initialize(topic_id, user=nil, options={})
|
def initialize(topic_id, user=nil, options={})
|
||||||
|
@ -20,7 +20,8 @@ class TopicView
|
||||||
|
|
||||||
@page = @page.to_i
|
@page = @page.to_i
|
||||||
@page = 1 if @page.zero?
|
@page = 1 if @page.zero?
|
||||||
@limit ||= SiteSetting.posts_chunksize
|
@chunk_size = options[:slow_platform] ? SiteSetting.posts_slow_chunksize : SiteSetting.posts_chunksize
|
||||||
|
@limit ||= @chunk_size
|
||||||
|
|
||||||
setup_filtered_posts
|
setup_filtered_posts
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,16 @@ describe TopicView do
|
||||||
lambda { TopicView.new(topic.id, admin) }.should_not raise_error
|
lambda { TopicView.new(topic.id, admin) }.should_not raise_error
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "chunk_size" do
|
||||||
|
it "returns `posts_chunksize` by default" do
|
||||||
|
TopicView.new(topic.id, coding_horror).chunk_size.should == SiteSetting.posts_chunksize
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns `posts_slow_chunksize` when slow_platform is true" do
|
||||||
|
tv = TopicView.new(topic.id, coding_horror, slow_platform: true)
|
||||||
|
tv.chunk_size.should == SiteSetting.posts_slow_chunksize
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "with a few sample posts" do
|
context "with a few sample posts" do
|
||||||
let!(:p1) { Fabricate(:post, topic: topic, user: first_poster, percent_rank: 1 )}
|
let!(:p1) { Fabricate(:post, topic: topic, user: first_poster, percent_rank: 1 )}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module("Discourse.PostStream");
|
module("Discourse.PostStream");
|
||||||
|
|
||||||
var buildStream = function(id, stream) {
|
var buildStream = function(id, stream) {
|
||||||
var topic = Discourse.Topic.create({id: id});
|
var topic = Discourse.Topic.create({id: id, chunk_size: 5});
|
||||||
var ps = topic.get('postStream');
|
var ps = topic.get('postStream');
|
||||||
if (stream) {
|
if (stream) {
|
||||||
ps.set('stream', stream);
|
ps.set('stream', stream);
|
||||||
|
@ -20,7 +20,6 @@ test('defaults', function() {
|
||||||
blank(postStream.get('posts'), "there are no posts in a stream by default");
|
blank(postStream.get('posts'), "there are no posts in a stream by default");
|
||||||
ok(!postStream.get('loaded'), "it has never loaded");
|
ok(!postStream.get('loaded'), "it has never loaded");
|
||||||
present(postStream.get('topic'));
|
present(postStream.get('topic'));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('appending posts', function() {
|
test('appending posts', function() {
|
||||||
|
@ -182,7 +181,6 @@ test("loading", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("nextWindow", function() {
|
test("nextWindow", function() {
|
||||||
Discourse.SiteSettings.posts_chunksize = 5;
|
|
||||||
var postStream = buildStream(1234, [1,2,3,5,8,9,10,11,13,14,15,16]);
|
var postStream = buildStream(1234, [1,2,3,5,8,9,10,11,13,14,15,16]);
|
||||||
|
|
||||||
blank(postStream.get('nextWindow'), 'With no posts loaded, the window is blank');
|
blank(postStream.get('nextWindow'), 'With no posts loaded, the window is blank');
|
||||||
|
@ -199,7 +197,6 @@ test("nextWindow", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("previousWindow", function() {
|
test("previousWindow", function() {
|
||||||
Discourse.SiteSettings.posts_chunksize = 5;
|
|
||||||
var postStream = buildStream(1234, [1,2,3,5,8,9,10,11,13,14,15,16]);
|
var postStream = buildStream(1234, [1,2,3,5,8,9,10,11,13,14,15,16]);
|
||||||
|
|
||||||
blank(postStream.get('previousWindow'), 'With no posts loaded, the window is blank');
|
blank(postStream.get('previousWindow'), 'With no posts loaded, the window is blank');
|
||||||
|
|
Loading…
Reference in a new issue