diff --git a/Changelog.md b/Changelog.md
index 721209c86ef697906227581db14b7377ab3764b3..003bb91e3ca5a233b5edb4871ab33c06561e8ef7 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -57,6 +57,7 @@ With the port to Bootstrap 3, app/views/terms/default.haml has a new structure.
 * Improve accessibility of a couple pages [#6227](https://github.com/diaspora/diaspora/pull/6227)
 * Capitalize "Powered by diaspora" [#6254](https://github.com/diaspora/diaspora/pull/6254)
 * Display username and avatar for NSFW posts in mobile view [#6245](https://github.com/diaspora/diaspora/6245)
+* Prevent multiple comment boxes on mobile [#6363](https://github.com/diaspora/diaspora/pull/6363)
 
 ## Features
 * Support color themes [#6033](https://github.com/diaspora/diaspora/pull/6033)
diff --git a/app/assets/javascripts/helpers/i18n.js b/app/assets/javascripts/helpers/i18n.js
index 9be574c459e155380a64b165755c86d322dafaca..f273165d4688b14768f94e1f62cb8f956bb18cd0 100644
--- a/app/assets/javascripts/helpers/i18n.js
+++ b/app/assets/javascripts/helpers/i18n.js
@@ -77,9 +77,12 @@ Diaspora.I18n = {
 
   reset: function() {
     this.locale.data = {};
+    this.locale.fallback.data = {};
 
-    if( arguments.length > 0 && !(_.isEmpty(arguments[0])) )
+    if(arguments.length > 0 && !(_.isEmpty(arguments[0]))) {
       this.locale.data = arguments[0];
+      this.locale.fallback.data = arguments[0];
+    }
   }
 };
 // @license-end
diff --git a/app/assets/javascripts/mobile/mobile_comments.js b/app/assets/javascripts/mobile/mobile_comments.js
index ed50b4d7f7045d197044a9606118cd8e1d295b78..3e6300b5f727897f81d07ac6862068c90b1a7523 100644
--- a/app/assets/javascripts/mobile/mobile_comments.js
+++ b/app/assets/javascripts/mobile/mobile_comments.js
@@ -4,162 +4,180 @@
  *   the COPYRIGHT file.
  */
 
-$(document).ready(function() {
+(function() {
+  Diaspora.Mobile = {};
+  Diaspora.Mobile.Comments = {
+    initialize: function() {
+      var self = this;
+      $(".stream").on("tap click", "a.back_to_stream_element_top", function() {
+        var bottomBar = $(this).closest(".bottom_bar").first();
+        var streamElement = bottomBar.parent();
+        $("html, body").animate({
+          scrollTop: streamElement.offset().top - 54
+        }, 1000);
+      });
 
-  $(".stream").on("tap click", "a.back_to_stream_element_top", function() {
-    var bottomBar = $(this).closest(".bottom_bar").first();
-    var streamElement = bottomBar.parent();
-    $("html, body").animate({
-      scrollTop: streamElement.offset().top - 54
-    }, 1000);
-  });
-
-  $(".stream").on("tap click", "a.show_comments", function(evt){
-    evt.preventDefault();
-    toggleComments($(this));
-  });
-
-  function toggleComments(toggleReactionsLink) {
-    if (toggleReactionsLink.hasClass("active")) {
-      hideComments(toggleReactionsLink);
-    } else {
-      showComments(toggleReactionsLink);
-    }
-  }
-
-  function hideComments(toggleReactionsLink) {
-    var bottomBar = toggleReactionsLink.closest(".bottom_bar").first(),
-        commentsContainer = commentsContainerLazy(bottomBar),
-        existingCommentsContainer = commentsContainer();
-    existingCommentsContainer.hide();
-    toggleReactionsLink.removeClass("active");
-  }
-
-  function showComments(toggleReactionsLink) {
-    var bottomBar = toggleReactionsLink.closest(".bottom_bar").first(),
-        commentsContainer = commentsContainerLazy(bottomBar),
-        existingCommentsContainer = commentsContainer(),
-        commentActionLink = bottomBar.find("a.comment-action");
-    if (existingCommentsContainer.length > 0) {
-      showLoadedComments(toggleReactionsLink, existingCommentsContainer, commentActionLink);
-    } else {
-      showUnloadedComments(toggleReactionsLink, bottomBar, commentActionLink);
-    }
-  }
-
-  function showLoadedComments(toggleReactionsLink, existingCommentsContainer, commentActionLink) {
-    existingCommentsContainer.show();
-    showCommentBox(commentActionLink);
-    toggleReactionsLink.addClass("active");
-    existingCommentsContainer.find("time.timeago").timeago();
-  }
-
-  function showUnloadedComments(toggleReactionsLink, bottomBar, commentActionLink) {
-    var commentsContainer = commentsContainerLazy(bottomBar);
-    $.ajax({
-      url: toggleReactionsLink.attr("href"),
-      success: function (data) {
-        $(data).insertAfter(bottomBar.children(".show_comments").first());
-        showCommentBox(commentActionLink);
-        toggleReactionsLink.addClass("active");
-        commentsContainer().find("time.timeago").timeago();
+      $(".stream").on("tap click", "a.show_comments", function(evt){
+        evt.preventDefault();
+        self.toggleComments($(this));
+      });
+
+      $(".stream").on("tap click", "a.comment-action", function(evt) {
+        evt.preventDefault();
+        self.showCommentBox($(this));
+        var bottomBar = $(this).closest(".bottom_bar").first();
+        var commentContainer = bottomBar.find(".comment_container").first();
+        self.scrollToOffset(commentContainer);
+      });
+
+      $(".stream").on("submit", ".new_comment", function(evt) {
+        evt.preventDefault();
+        var form = $(this);
+        $.post(form.attr("action")+"?format=mobile", form.serialize(), function(data) {
+          self.updateStream(form, data);
+        }, "html");
+      });
+    },
+
+    toggleComments: function(toggleReactionsLink) {
+      if(toggleReactionsLink.hasClass("loading")) { return; }
+      if (toggleReactionsLink.hasClass("active")) {
+        this.hideComments(toggleReactionsLink);
+      } else {
+        this.showComments(toggleReactionsLink);
       }
-    });
-  }
-
-  function commentsContainerLazy(bottomBar) {
-    return function() {
-      return bottomBar.find(".comment_container").first();
-    };
-  }
-
-  $(".stream").on("tap click", "a.comment-action", function(evt) {
-    evt.preventDefault();
-    showCommentBox(this);
-    var bottomBar = $(this).closest(".bottom_bar").first();
-    var commentContainer = bottomBar.find(".comment_container").first();
-    scrollToOffset(commentContainer);
-  });
-  var scrollToOffset = function(commentsContainer){
-    var commentCount = commentsContainer.find("li.comment").length;
-    if ( commentCount > 3 ) {
-      var lastComment = commentsContainer.find("li:nth-child("+(commentCount-3)+")");
-      $("html,body").animate({
-        scrollTop: lastComment.offset().top
-      }, 1000);
-    }
-  };
+    },
+
+    hideComments: function(toggleReactionsLink) {
+      var bottomBar = toggleReactionsLink.closest(".bottom_bar").first(),
+          commentsContainer = this.commentsContainerLazy(bottomBar),
+          existingCommentsContainer = commentsContainer();
+      existingCommentsContainer.hide();
+      toggleReactionsLink.removeClass("active");
+    },
+
+    showComments: function(toggleReactionsLink) {
+      var bottomBar = toggleReactionsLink.closest(".bottom_bar").first(),
+          commentsContainer = this.commentsContainerLazy(bottomBar),
+          existingCommentsContainer = commentsContainer(),
+          commentActionLink = bottomBar.find("a.comment-action");
+      if (existingCommentsContainer.length > 0) {
+        this.showLoadedComments(toggleReactionsLink, existingCommentsContainer, commentActionLink);
+      } else {
+        this.showUnloadedComments(toggleReactionsLink, bottomBar, commentActionLink);
+      }
+    },
+
+    showLoadedComments: function(toggleReactionsLink, existingCommentsContainer, commentActionLink) {
+      toggleReactionsLink.addClass("active");
+      existingCommentsContainer.show();
+      this.showCommentBox(commentActionLink);
+      existingCommentsContainer.find("time.timeago").timeago();
+    },
+
+    showUnloadedComments: function(toggleReactionsLink, bottomBar, commentActionLink) {
+      toggleReactionsLink.addClass("loading");
+      var commentsContainer = this.commentsContainerLazy(bottomBar);
+      var self = this;
+      $.ajax({
+        url: toggleReactionsLink.attr("href"),
+        success: function (data) {
+          toggleReactionsLink.addClass("active").removeClass("loading");
+          $(data).insertAfter(bottomBar.children(".show_comments").first());
+          self.showCommentBox(commentActionLink);
+          commentsContainer().find("time.timeago").timeago();
+        },
+        error: function() {
+          toggleReactionsLink.removeClass("loading");
+        }
+      });
+    },
+
+    commentsContainerLazy: function(bottomBar) {
+      return function() {
+        return bottomBar.find(".comment_container").first();
+      };
+    },
+
+    scrollToOffset: function(commentsContainer){
+      var commentCount = commentsContainer.find("li.comment").length;
+      if ( commentCount > 3 ) {
+        var lastComment = commentsContainer.find("li:nth-child("+(commentCount-3)+")");
+        $("html,body").animate({
+          scrollTop: lastComment.offset().top
+        }, 1000);
+      }
+    },
 
-  function showCommentBox(link){
-    var commentActionLink = $(link);
-    if(commentActionLink.hasClass("inactive")) {
+    showCommentBox: function(link){
+      if(!link.hasClass("inactive") || link.hasClass("loading")) { return; }
+      var self = this;
       $.ajax({
-        url: commentActionLink.attr("href"),
+        url: link.attr("href"),
         beforeSend: function(){
-          commentActionLink.addClass("loading");
+          link.addClass("loading");
+        },
+        context: link,
+        success: function(data) {
+          self.appendCommentBox.call(this, link, data);
         },
-        context: commentActionLink,
-        success: function(data){
-          appendCommentBox.call(this, commentActionLink, data);
+        error: function() {
+          link.removeClass("loading");
         }
       });
+    },
+
+    appendCommentBox: function(link, data) {
+      link.removeClass("loading");
+      link.removeClass("inactive");
+      var bottomBar = link.closest(".bottom_bar").first();
+      bottomBar.append(data);
+      var textArea = bottomBar.find("textarea.comment_box").first()[0];
+      autosize(textArea);
+    },
+
+    updateStream: function(form, data) {
+      var bottomBar = form.closest(".bottom_bar").first();
+      this.addNewComments(bottomBar, data);
+      this.updateCommentCount(bottomBar);
+      this.updateReactionCount(bottomBar);
+      this.handleCommentShowing(form, bottomBar);
+      bottomBar.find("time.timeago").timeago();
+    },
+
+    addNewComments: function(bottomBar, data) {
+      var commentsContainer = bottomBar.find(".comment_container").first();
+      var comments = commentsContainer.find(".comments").first();
+      comments.append(data);
+    },
+
+    // Fix for no comments
+    updateCommentCount: function(bottomBar) {
+      var commentCount = bottomBar.find(".comment_count");
+      commentCount.text(commentCount.text().replace(/(\d+)/, function (match) {
+        return parseInt(match) + 1;
+      }));
+    },
+
+    // Fix for no reactions
+    updateReactionCount: function(bottomBar) {
+      var toggleReactionsLink = bottomBar.find(".show_comments").first();
+      toggleReactionsLink.text(toggleReactionsLink.text().replace(/(\d+)/, function (match) {
+        return parseInt(match) + 1;
+      }));
+    },
+
+    handleCommentShowing: function(form, bottomBar) {
+      var formContainer = form.parent();
+      formContainer.remove();
+      var commentActionLink = bottomBar.find("a.comment-action").first();
+      commentActionLink.addClass("inactive");
+      var toggleReactionsLink = bottomBar.find(".show_comments").first();
+      this.showComments(toggleReactionsLink);
     }
-  }
-
-  function appendCommentBox(link, data) {
-    link.removeClass("loading");
-    link.removeClass("inactive");
-    var bottomBar = link.closest(".bottom_bar").first();
-    bottomBar.append(data);
-    var textArea = bottomBar.find("textarea.comment_box").first()[0];
-    autosize(textArea);
-  }
-
-  $(".stream").on("submit", ".new_comment", function(evt) {
-    evt.preventDefault();
-    var form = $(this);
-    $.post(form.attr("action")+"?format=mobile", form.serialize(), function(data) {
-      updateStream(form, data);
-    }, "html");
-  });
-
-  function updateStream(form, data) {
-    var bottomBar = form.closest(".bottom_bar").first();
-    addNewComments(bottomBar, data);
-    updateCommentCount(bottomBar);
-    updateReactionCount(bottomBar);
-    handleCommentShowing(form, bottomBar);
-    bottomBar.find("time.timeago").timeago();
-  }
-
-  function addNewComments(bottomBar, data) {
-    var commentsContainer = bottomBar.find(".comment_container").first();
-    var comments = commentsContainer.find(".comments").first();
-    comments.append(data);
-  }
-
-  // Fix for no comments
-  function updateCommentCount(bottomBar) {
-    var commentCount = bottomBar.find(".comment_count");
-    commentCount.text(commentCount.text().replace(/(\d+)/, function (match) {
-      return parseInt(match) + 1;
-    }));
-  }
-
-  // Fix for no reactions
-  function updateReactionCount(bottomBar) {
-    var toggleReactionsLink = bottomBar.find(".show_comments").first();
-    toggleReactionsLink.text(toggleReactionsLink.text().replace(/(\d+)/, function (match) {
-      return parseInt(match) + 1;
-    }));
-  }
-
-  function handleCommentShowing(form, bottomBar) {
-    var formContainer = form.parent();
-    formContainer.remove();
-    var commentActionLink = bottomBar.find("a.comment-action").first();
-    commentActionLink.addClass("inactive");
-    var toggleReactionsLink = bottomBar.find(".show_comments").first();
-    showComments(toggleReactionsLink);
-  }
+  };
+})();
+
+$(document).ready(function() {
+  Diaspora.Mobile.Comments.initialize();
 });
diff --git a/spec/controllers/jasmine_fixtures/aspects_spec.rb b/spec/controllers/jasmine_fixtures/aspects_spec.rb
index bdbf026baef8ea68148840e1af91d3f5fba33a0c..e61faba7b1eb10c31cb8344b433bd458dafbc25f 100644
--- a/spec/controllers/jasmine_fixtures/aspects_spec.rb
+++ b/spec/controllers/jasmine_fixtures/aspects_spec.rb
@@ -58,6 +58,13 @@ describe StreamsController, :type => :controller do
         save_fixture(html_for("body"), "aspects_index_post_with_comments")
       end
 
+      it "generates a mobile jasmine fixture with a post with comments", fixture: true do
+        message = bob.post(:status_message, text: "HALO WHIRLED", to: @bob.aspects.where(name: "generic").first.id)
+        5.times { bob.comment!(message, "what") }
+        get :aspects, format: :mobile
+        save_fixture(html_for("body"), "aspects_index_mobile_post_with_comments")
+      end
+
       it 'generates a jasmine fixture with a followed tag', :fixture => true do
         @tag = ActsAsTaggableOn::Tag.create!(:name => "partytimeexcellent")
         TagFollowing.create!(:tag => @tag, :user => alice)
diff --git a/spec/javascripts/mobile/mobile_comments_spec.js b/spec/javascripts/mobile/mobile_comments_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..24f4bdbcb8e769e961fe0b1a58b802b6d365112f
--- /dev/null
+++ b/spec/javascripts/mobile/mobile_comments_spec.js
@@ -0,0 +1,119 @@
+describe("Diaspora.Mobile.Comments", function(){
+  describe("toggleComments", function() {
+    beforeEach(function() {
+      spec.loadFixture("aspects_index_mobile_post_with_comments");
+      this.link = $(".stream .show_comments").first();
+      spyOn(Diaspora.Mobile.Comments, "showComments");
+      spyOn(Diaspora.Mobile.Comments, "hideComments");
+    });
+
+    it("calls showComments", function() {
+      Diaspora.Mobile.Comments.toggleComments(this.link);
+      expect(Diaspora.Mobile.Comments.showComments).toHaveBeenCalled();
+      expect(Diaspora.Mobile.Comments.hideComments).not.toHaveBeenCalled();
+    });
+
+    it("calls hideComments if the link class is 'active'", function() {
+      this.link.addClass("active");
+      Diaspora.Mobile.Comments.toggleComments(this.link);
+      expect(Diaspora.Mobile.Comments.showComments).not.toHaveBeenCalled();
+      expect(Diaspora.Mobile.Comments.hideComments).toHaveBeenCalled();
+    });
+
+    it("doesn't call any function if the link class is 'loading'", function() {
+      this.link.addClass("loading");
+      Diaspora.Mobile.Comments.toggleComments(this.link);
+      expect(Diaspora.Mobile.Comments.showComments).not.toHaveBeenCalled();
+      expect(Diaspora.Mobile.Comments.hideComments).not.toHaveBeenCalled();
+    });
+  });
+
+  describe("showUnloadedComments", function() {
+    beforeEach(function() {
+      spec.loadFixture("aspects_index_mobile_post_with_comments");
+      this.link = $(".stream .show_comments").first();
+      this.bottomBar = this.link.closest(".bottom_bar").first();
+      this.commentActionLink = this.bottomBar.find("a.comment-action");
+    });
+
+    it("adds the 'loading' class to the link", function() {
+      Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
+      expect($(".show_comments").first()).toHaveClass("loading");
+    });
+
+    it("removes the 'loading' class if the request failed", function() {
+      Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
+      jasmine.Ajax.requests.mostRecent().respondWith({status: 400});
+      expect($(".show_comments").first()).not.toHaveClass("loading");
+    });
+
+    it("adds the 'active' class if the request succeeded", function() {
+      Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
+      jasmine.Ajax.requests.mostRecent().respondWith({status: 200, contentType: "text/plain", responseText: "test"});
+      expect($(".show_comments").first()).toHaveClass("active");
+      expect($(".show_comments").first()).not.toHaveClass("loading");
+    });
+
+    it("calls showCommentBox", function() {
+      spyOn(Diaspora.Mobile.Comments, "showCommentBox");
+      Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
+      jasmine.Ajax.requests.mostRecent().respondWith({status: 200, contentType: "text/plain", responseText: "test"});
+      expect(Diaspora.Mobile.Comments.showCommentBox).toHaveBeenCalledWith(this.commentActionLink);
+    });
+
+    it("adds the response text to the comments list", function() {
+      Diaspora.Mobile.Comments.showUnloadedComments(this.link, this.bottomBar, this.commentActionLink);
+      jasmine.Ajax.requests.mostRecent().respondWith({
+        status: 200,
+        contentType: "text/plain",
+        responseText: "<div class=\"commentContainerForTest\">new comments</div>"
+      });
+      expect($(".stream .stream_element").first()).toContainElement(".commentContainerForTest");
+    });
+  });
+
+  describe("showCommentBox", function() {
+    beforeEach(function() {
+      spec.loadFixture("aspects_index_mobile_post_with_comments");
+      this.link = $(".stream .comment-action").first();
+    });
+
+    it("adds the 'loading' class to the link", function() {
+      Diaspora.Mobile.Comments.showCommentBox(this.link);
+      expect($(".comment-action").first()).toHaveClass("loading");
+    });
+
+    it("removes the 'loading' class if the request failed", function() {
+      Diaspora.Mobile.Comments.showCommentBox(this.link);
+      jasmine.Ajax.requests.mostRecent().respondWith({status: 400});
+      expect($(".comment-action").first()).not.toHaveClass("loading");
+    });
+
+    it("fires an AJAX call", function() {
+      spyOn(jQuery, "ajax");
+      Diaspora.Mobile.Comments.showCommentBox(this.link);
+      expect(jQuery.ajax).toHaveBeenCalled();
+    });
+
+    it("calls appendCommentBox", function() {
+      spyOn(Diaspora.Mobile.Comments, "appendCommentBox");
+      Diaspora.Mobile.Comments.showCommentBox(this.link);
+      jasmine.Ajax.requests.mostRecent().respondWith({status: 200, contentType: "text/plain", responseText: "test"});
+      expect(Diaspora.Mobile.Comments.appendCommentBox).toHaveBeenCalledWith(this.link, "test");
+    });
+
+    it("doesn't do anything if the link class is 'loading'", function() {
+      spyOn(jQuery, "ajax");
+      this.link.addClass("loading");
+      Diaspora.Mobile.Comments.showCommentBox(this.link);
+      expect(jQuery.ajax).not.toHaveBeenCalled();
+    });
+
+    it("doesn't do anything if the link class is not 'inactive'", function() {
+      spyOn(jQuery, "ajax");
+      this.link.removeClass("inactive");
+      Diaspora.Mobile.Comments.showCommentBox(this.link);
+      expect(jQuery.ajax).not.toHaveBeenCalled();
+    });
+  });
+});
diff --git a/spec/javascripts/widgets/i18n-spec.js b/spec/javascripts/widgets/i18n-spec.js
index 2315957ce93afb27cbb0acd9aa2796cc8d038fa2..17a469611b1e0318a3d3091365912ca10eaa8f06 100644
--- a/spec/javascripts/widgets/i18n-spec.js
+++ b/spec/javascripts/widgets/i18n-spec.js
@@ -90,6 +90,7 @@ describe("Diaspora.I18n", function() {
       Diaspora.I18n.load(locale, "en", locale);
       Diaspora.I18n.reset();
       expect(Diaspora.I18n.locale.data).toEqual({});
+      expect(Diaspora.I18n.locale.fallback.data).toEqual({});
     });
 
     it("sets the locale to only a specific value", function() {
@@ -97,6 +98,7 @@ describe("Diaspora.I18n", function() {
       Diaspora.I18n.load(locale, "en", locale);
       Diaspora.I18n.reset(data);
       expect(Diaspora.I18n.locale.data).toEqual(data);
+      expect(Diaspora.I18n.locale.fallback.data).toEqual(data);
     });
   });
 });