diff --git a/app/assets/javascripts/discourse.js b/app/assets/javascripts/discourse.js index ebfadc83d3c..7fb9937720b 100644 --- a/app/assets/javascripts/discourse.js +++ b/app/assets/javascripts/discourse.js @@ -143,8 +143,7 @@ Discourse = Ember.Application.createWithMixins(Discourse.Ajax, { bootbox.animate(false); bootbox.backdrop(true); // clicking outside a bootbox modal closes it - Discourse.Session.currentProp('mobileDevice', $html.hasClass('mobile-device')); - Discourse.Session.currentProp('mobileView', $html.hasClass('mobile-view')); + Discourse.Mobile.init(); setInterval(function(){ Discourse.Formatter.updateRelativeAge($('.relative-date')); diff --git a/app/assets/javascripts/discourse/components/mobile.js b/app/assets/javascripts/discourse/components/mobile.js new file mode 100644 index 00000000000..3678ccd2451 --- /dev/null +++ b/app/assets/javascripts/discourse/components/mobile.js @@ -0,0 +1,36 @@ +/** + A class that is responsible for logic related to mobile devices. + + @class Mobile + @namespace Discourse + @module Discourse +**/ +Discourse.Mobile = { + + isMobileDevice: false, + mobileView: false, + + init: function() { + var $html = $('html'); + this.isMobileDevice = $html.hasClass('mobile-device'); + this.mobileView = $html.hasClass('mobile-view'); + + if (localStorage && localStorage.mobileView) { + var savedValue = (localStorage.mobileView === 'true' ? true : false); + if (savedValue !== this.mobileView) { + this.reloadPage(savedValue); + } + } + }, + + toggleMobileView: function() { + if (localStorage) { + localStorage.mobileView = !this.mobileView; + } + this.reloadPage(!this.mobileView); + }, + + reloadPage: function(mobile) { + window.location.assign(window.location.pathname + '?mobile_view=' + (mobile ? '1' : '0')); + } +}; diff --git a/app/assets/javascripts/discourse/controllers/header_controller.js b/app/assets/javascripts/discourse/controllers/header_controller.js index 613c1586dfc..bf52f41a984 100644 --- a/app/assets/javascripts/discourse/controllers/header_controller.js +++ b/app/assets/javascripts/discourse/controllers/header_controller.js @@ -25,15 +25,15 @@ Discourse.HeaderController = Discourse.Controller.extend({ }.property('currentUser', 'topic.isPrivateMessage'), mobileDevice: function() { - return Discourse.Session.currentProp('mobileDevice'); + return Discourse.Mobile.isMobileDevice; }.property(), mobileView: function() { - return Discourse.Session.currentProp('mobileView'); + return Discourse.Mobile.mobileView; }.property(), toggleMobileView: function() { - window.location.assign(window.location.pathname + '?mobile_view=' + (Discourse.Session.currentProp('mobileView') ? '0' : '1')); + Discourse.Mobile.toggleMobileView(); } }); diff --git a/app/assets/javascripts/discourse/views/header_view.js b/app/assets/javascripts/discourse/views/header_view.js index 03abe05a275..458385466c6 100644 --- a/app/assets/javascripts/discourse/views/header_view.js +++ b/app/assets/javascripts/discourse/views/header_view.js @@ -98,7 +98,7 @@ Discourse.HeaderView = Discourse.View.extend({ **/ logoHTML: function() { var result = "
"; - if (!Discourse.Session.currentProp('mobileView') && this.get('controller.showExtraInfo')) { + if (!Discourse.Mobile.mobileView && this.get('controller.showExtraInfo')) { var logoSmall = Discourse.SiteSettings.logo_small_url; if (logoSmall && logoSmall.length > 1) { result += ""; diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 5b98c20c197..605d0399e3f 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -117,8 +117,7 @@ module ApplicationHelper end def mobile_device? - # For now, don't show mobile view unless you put ?mobile_view=1 in the URL. - # request.user_agent =~ /Mobile|webOS/ - false + # TODO: this is dumb. user agent matching is a doomed approach. a better solution is coming. + request.user_agent =~ /Mobile|webOS/ and !(request.user_agent =~ /iPad/) end end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index aa16b6adbd5..f86fcff8e98 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -13,18 +13,28 @@ describe ApplicationHelper do helper.mobile_view?.should be_false end - it "is false if mobile_view is not set and user agent is not mobile" do - controller.request.stubs(:user_agent).returns('Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.17 Safari/537.36') - helper.mobile_view?.should be_false - end + context "mobile_view is not set" do + it "is false if user agent is not mobile" do + controller.request.stubs(:user_agent).returns('Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.17 Safari/537.36') + helper.mobile_view?.should be_false + end - #it "is true if mobile_view is not set and user agent is mobile" do - it "is always false, even if user agent is for mobile device... for now..." do - controller.request.stubs(:user_agent).returns('Mozilla/5.0 (iPhone; U; ru; CPU iPhone OS 4_2_1 like Mac OS X; ru) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5') - #helper.mobile_view?.should be_true - # TODO: It's always false for now - helper.mobile_view?.should be_false + it "is true for iPhone" do + controller.request.stubs(:user_agent).returns('Mozilla/5.0 (iPhone; U; ru; CPU iPhone OS 4_2_1 like Mac OS X; ru) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148a Safari/6533.18.5') + helper.mobile_view?.should be_true + end + + it "is false for iPad" do + controller.request.stubs(:user_agent).returns("Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3") + helper.mobile_view?.should be_false + end + + it "is false for Android tablet" do + controller.request.stubs(:user_agent).returns("Mozilla/5.0 (Linux; Android 4.1.2; Nexus 7 Build/JZ054K) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19") + helper.mobile_view?.should be_false + end end end + end