diff --git a/app/assets/javascripts/discourse/components/discourse-topic.js.es6 b/app/assets/javascripts/discourse/components/discourse-topic.js.es6
index 96c11ab7465..15716de7ad3 100644
--- a/app/assets/javascripts/discourse/components/discourse-topic.js.es6
+++ b/app/assets/javascripts/discourse/components/discourse-topic.js.es6
@@ -12,6 +12,9 @@ function highlight(postNumber) {
$contents.on("animationend", () => $contents.removeClass("highlighted"));
}
+// used to determine scroll direction on mobile
+let lastScroll, scrollDirection, delta;
+
export default Ember.Component.extend(AddArchetypeClass, Scrolling, {
userFilters: Ember.computed.alias("topic.userFilters"),
classNameBindings: [
@@ -94,6 +97,23 @@ export default Ember.Component.extend(AddArchetypeClass, Scrolling, {
this.appEvents.trigger("header:hide-topic");
}
});
+ // setup mobile scroll logo
+ if (this.site.mobileView) {
+ this.appEvents.on("topic:scrolled", offset =>
+ this.mobileScrollGaurd(offset)
+ );
+ // used to animate header contents on scroll
+ this.appEvents.on("header:show-topic", () => {
+ $("header.d-header")
+ .removeClass("scroll-up")
+ .addClass("scroll-down");
+ });
+ this.appEvents.on("header:hide-topic", () => {
+ $("header.d-header")
+ .removeClass("scroll-down")
+ .addClass("scroll-up");
+ });
+ }
},
willDestroyElement() {
@@ -109,6 +129,11 @@ export default Ember.Component.extend(AddArchetypeClass, Scrolling, {
// this happens after route exit, stuff could have trickled in
this.appEvents.trigger("header:hide-topic");
this.appEvents.off("post:highlight");
+ // mobile scroll logo clean up.
+ if (this.site.mobileView) {
+ this.appEvents.off("topic:scrolled");
+ $("header.d-header").removeClass("scroll-down scroll-up");
+ }
},
@observes("Discourse.hasFocus")
@@ -123,9 +148,18 @@ export default Ember.Component.extend(AddArchetypeClass, Scrolling, {
},
showTopicInHeader(topic, offset) {
- return offset > this.get("dockAt");
+ // conditions for showing topic title in the header for mobile
+ if (
+ this.site.mobileView &&
+ scrollDirection !== "up" &&
+ offset > this.dockAt
+ ) {
+ return true;
+ // condition for desktops
+ } else {
+ return offset > this.dockAt;
+ }
},
-
// The user has scrolled the window, or it is finished rendering and ready for processing.
scrolled() {
if (this.isDestroyed || this.isDestroying || this._state !== "inDOM") {
@@ -161,5 +195,23 @@ export default Ember.Component.extend(AddArchetypeClass, Scrolling, {
// Trigger a scrolled event
this.appEvents.trigger("topic:scrolled", offset);
+ },
+
+ // determines scroll direction, triggers header topic info on mobile
+ // and ensures that the switch happens only once per scroll direction change
+ mobileScrollGaurd(offset) {
+ // user hasn't scrolled past topic title.
+ if (offset < this.dockAt) return;
+
+ delta = offset - lastScroll;
+ // 3px buffer so that the switch doesn't happen with tiny scrolls
+ if (delta > 3 && scrollDirection !== "down") {
+ scrollDirection = "down";
+ this.appEvents.trigger("header:show-topic", this.topic);
+ } else if (delta < -3 && scrollDirection !== "up") {
+ scrollDirection = "up";
+ this.appEvents.trigger("header:hide-topic");
+ }
+ lastScroll = offset;
}
});
diff --git a/app/assets/javascripts/discourse/components/topic-progress.js.es6 b/app/assets/javascripts/discourse/components/topic-progress.js.es6
index eca9ebb1243..1a107c96449 100644
--- a/app/assets/javascripts/discourse/components/topic-progress.js.es6
+++ b/app/assets/javascripts/discourse/components/topic-progress.js.es6
@@ -1,3 +1,4 @@
+import { getOwner } from "discourse-common/lib/get-owner";
import {
default as computed,
observes
@@ -154,15 +155,14 @@ export default Ember.Component.extend({
const $wrapper = this.$();
if (!$wrapper || $wrapper.length === 0) return;
- const offset = window.pageYOffset || $("html").scrollTop();
- const progressHeight = this.site.mobileView
- ? 0
- : $("#topic-progress").height();
- const maximumOffset = $("#topic-bottom").offset().top + progressHeight;
- const windowHeight = $(window).height();
- const composerHeight = $("#reply-control").height() || 0;
- const isDocked = offset >= maximumOffset - windowHeight + composerHeight;
- const bottom = $("body").height() - maximumOffset;
+ const offset = window.pageYOffset || $("html").scrollTop(),
+ progressHeight = this.site.mobileView ? 0 : $("#topic-progress").height(),
+ maximumOffset = $("#topic-bottom").offset().top + progressHeight,
+ windowHeight = $(window).height(),
+ bodyHeight = $("body").height(),
+ composerHeight = $("#reply-control").height() || 0,
+ isDocked = offset >= maximumOffset - windowHeight + composerHeight,
+ bottom = bodyHeight - maximumOffset;
if (composerHeight > 0) {
$wrapper.css("bottom", isDocked ? bottom : composerHeight);
@@ -178,6 +178,23 @@ export default Ember.Component.extend({
} else {
$wrapper.css("right", "1em");
}
+
+ // switch mobile scroll logo at the very bottom of topics
+ const isIOS = this.capabilities.isIOS,
+ switchHeight = bodyHeight - offset - windowHeight,
+ appEvents = getOwner(this).lookup("app-events:main");
+
+ if (isIOS && switchHeight < -10) {
+ // match elastic-scroll behaviour in iOS
+ setTimeout(function() {
+ appEvents.trigger("header:hide-topic");
+ }, 300);
+ } else if (!isIOS && switchHeight < 5) {
+ // normal switch for everyone else
+ setTimeout(function() {
+ appEvents.trigger("header:hide-topic");
+ }, 300);
+ }
},
click(e) {
diff --git a/app/assets/javascripts/discourse/widgets/header-contents.js.es6 b/app/assets/javascripts/discourse/widgets/header-contents.js.es6
index b339b08b314..82bae85ec42 100644
--- a/app/assets/javascripts/discourse/widgets/header-contents.js.es6
+++ b/app/assets/javascripts/discourse/widgets/header-contents.js.es6
@@ -5,9 +5,9 @@ createWidget("header-contents", {
tagName: "div.contents.clearfix",
template: hbs`
{{attach widget="home-logo" attrs=attrs}}
-
{{yield}}
{{#if attrs.topic}}
{{attach widget="header-topic-info" attrs=attrs}}
{{/if}}
+ {{yield}}
`
});
diff --git a/app/assets/javascripts/discourse/widgets/header-topic-info.js.es6 b/app/assets/javascripts/discourse/widgets/header-topic-info.js.es6
index e02f388a4a3..6f79883cae6 100644
--- a/app/assets/javascripts/discourse/widgets/header-topic-info.js.es6
+++ b/app/assets/javascripts/discourse/widgets/header-topic-info.js.es6
@@ -20,7 +20,7 @@ export default createWidget("header-topic-info", {
if (href) {
heading.push(
h(
- "a",
+ "a.private-message-glyph-wrapper",
{ attributes: { href } },
h("span.private-message-glyph", iconNode("envelope"))
)
@@ -47,6 +47,7 @@ export default createWidget("header-topic-info", {
const title = [h("h1", heading)];
const category = topic.get("category");
+
if (loaded || category) {
if (
category &&
@@ -54,12 +55,15 @@ export default createWidget("header-topic-info", {
!this.siteSettings.suppress_uncategorized_badge)
) {
const parentCategory = category.get("parentCategory");
+ const categories = [];
if (parentCategory) {
- title.push(
+ categories.push(
this.attach("category-link", { category: parentCategory })
);
}
- title.push(this.attach("category-link", { category }));
+ categories.push(this.attach("category-link", { category }));
+
+ title.push(h("div.categories-wrapper", categories));
}
let extra = [];
diff --git a/app/assets/javascripts/discourse/widgets/home-logo.js.es6 b/app/assets/javascripts/discourse/widgets/home-logo.js.es6
index c0532d14712..5672cff2852 100644
--- a/app/assets/javascripts/discourse/widgets/home-logo.js.es6
+++ b/app/assets/javascripts/discourse/widgets/home-logo.js.es6
@@ -26,15 +26,15 @@ export default createWidget("home-logo", {
const logoUrl = siteSettings.site_logo_url || "";
const title = siteSettings.title;
- if (!mobileView && this.attrs.minimized) {
+ if (this.attrs.minimized) {
const logoSmallUrl = siteSettings.site_logo_small_url || "";
if (logoSmallUrl.length) {
return h("img#site-logo.logo-small", {
key: "logo-small",
attributes: {
src: Discourse.getURL(logoSmallUrl),
- width: 33,
- height: 33,
+ width: 36,
+ height: 36,
alt: title
}
});
@@ -49,7 +49,7 @@ export default createWidget("home-logo", {
} else if (logoUrl.length) {
return h("img#site-logo.logo-big", {
key: "logo-big",
- attributes: { src: Discourse.getURL(logoUrl), alt: title }
+ attributes: { src: Discourse.getURL(logoUrl), height: 36, alt: title }
});
} else {
return h("h1#site-text-logo.text-logo", { key: "logo-text" }, title);
diff --git a/app/assets/stylesheets/common/base/header.scss b/app/assets/stylesheets/common/base/header.scss
index ec9313d4dc9..6ed5598e163 100644
--- a/app/assets/stylesheets/common/base/header.scss
+++ b/app/assets/stylesheets/common/base/header.scss
@@ -1,4 +1,6 @@
.d-header {
+ display: flex;
+ align-items: center;
width: 100%;
position: absolute;
top: 0;
@@ -6,35 +8,46 @@
background-color: $header_background;
box-shadow: shadow("header");
+ > .wrap {
+ width: 100%;
+ height: 100%;
+ .contents {
+ display: flex;
+ align-items: center;
+ height: 100%;
+ }
+ }
+
.docked & {
position: fixed;
backface-visibility: hidden; /** do magic for scrolling performance **/
}
- .contents {
- margin: 8px 0;
- }
-
.title {
- float: left;
+ display: flex;
+ align-items: center;
+ height: 100%;
a,
a:visited {
color: $header_primary;
}
}
+ // the logo height is set in the home-logo widget. This ensures we get a scaled
+ // width that respects the aspect ratio of the image
#site-logo {
- max-height: 2.8571em;
+ width: auto;
}
.d-icon-home {
- font-size: 1.643em;
+ font-size: $font-up-5;
}
.panel {
- float: right;
position: relative;
display: flex;
+ flex: 0 0 auto;
+ margin-left: auto;
align-items: center;
}
@@ -195,3 +208,88 @@
#search-term::-ms-clear {
display: none;
}
+
+// topic info in the header
+.extra-info-wrapper {
+ display: flex;
+ align-items: center;
+ flex: 1 1 0%; // unit on flex-basis is required for IE11
+ height: 100%;
+ line-height: $line-height-medium;
+ padding: 0 1.5em 0 0.5em;
+ // we need to hide overflow in both to truncate the title in a flexbox
+ overflow: hidden;
+ .extra-info {
+ overflow: hidden;
+ width: 100%;
+ -webkit-animation: fadein 0.5s;
+ animation: fadein 0.5s;
+ }
+ .topic-link {
+ color: $header_primary;
+ display: block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+ .topic-statuses {
+ margin-top: -2px;
+ float: left;
+ padding: 0;
+ i {
+ color: $header_primary;
+ }
+ .d-icon-envelope {
+ color: $danger;
+ }
+ .d-icon-lock {
+ padding-top: 0.15em;
+ }
+ .unpinned {
+ color: $header_primary;
+ }
+ }
+ h1 {
+ margin: 0 0 0.25em 0;
+ font-size: $font-up-3;
+ width: 100%;
+ }
+ .categories-wrapper {
+ display: inline-flex;
+ max-width: 100%;
+ // only truncate the last category name.
+ > a:last-of-type {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+ }
+ .badge-wrapper {
+ margin-right: 8px;
+ }
+ .badge-wrapper.bullet {
+ .badge-category-parent-bg,
+ .badge-category-bg {
+ min-width: 5px;
+ }
+ }
+ .topic-header-extra {
+ display: inline-flex;
+ align-items: center;
+ max-width: 100%;
+ flex: 1 0 0%; // unit on flex-basis is required for IE11
+ .discourse-tags {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ .discourse-tag {
+ display: inline;
+ }
+ }
+ }
+ // if a topic has both categories and tags, the tag container should shrink
+ // instead of wrapping to the next line.
+ .categories-wrapper + .topic-header-extra {
+ min-width: 0;
+ }
+}
diff --git a/app/assets/stylesheets/common/base/tagging.scss b/app/assets/stylesheets/common/base/tagging.scss
index 5c82fdbd59f..0e2e9346967 100644
--- a/app/assets/stylesheets/common/base/tagging.scss
+++ b/app/assets/stylesheets/common/base/tagging.scss
@@ -37,19 +37,6 @@
}
}
-.topic-header-extra .discourse-tag {
- -webkit-animation: fadein 0.7s;
- animation: fadein 0.7s;
-}
-
-.bullet + .topic-header-extra {
- display: block;
-}
-
-.box + .topic-header-extra {
- display: inline-block;
-}
-
.topic-category {
display: flex;
flex-wrap: wrap;
diff --git a/app/assets/stylesheets/common/base/topic.scss b/app/assets/stylesheets/common/base/topic.scss
index 82233f44ee5..a1c19b57442 100644
--- a/app/assets/stylesheets/common/base/topic.scss
+++ b/app/assets/stylesheets/common/base/topic.scss
@@ -60,8 +60,6 @@
.title-wrapper {
display: flex;
flex-wrap: wrap;
- width: 90%;
- align-items: flex-end;
.btn-small {
margin: 0 6px 0 0;
}
@@ -151,12 +149,6 @@ a.badge-category {
clear: both;
}
-.extra-info-wrapper {
- .badge-wrapper {
- float: left;
- }
-}
-
.has-pending-posts {
padding: 0.5em;
background-color: $highlight-medium;
diff --git a/app/assets/stylesheets/desktop/discourse.scss b/app/assets/stylesheets/desktop/discourse.scss
index df19506ad8e..1bd3dac3615 100644
--- a/app/assets/stylesheets/desktop/discourse.scss
+++ b/app/assets/stylesheets/desktop/discourse.scss
@@ -8,10 +8,6 @@ body.widget-dragging {
cursor: ns-resize;
}
-header {
- margin-bottom: 15px;
-}
-
// Common classes
.boxed {
height: 100%;
diff --git a/app/assets/stylesheets/desktop/header.scss b/app/assets/stylesheets/desktop/header.scss
index e4b20e264f4..3f53844ff4e 100644
--- a/app/assets/stylesheets/desktop/header.scss
+++ b/app/assets/stylesheets/desktop/header.scss
@@ -4,16 +4,21 @@
.d-header {
left: 0;
- padding-top: 3px;
- height: 4.2857em;
- .d-icon-home {
- padding: 8px;
- font-size: $font-up-5;
- }
+ height: 4.2858em;
+ margin-bottom: 15px;
- .site-text-logo {
- position: relative;
- top: 10px;
+ #site-text-logo {
+ font-size: $font-up-3;
+ margin: 0;
+ }
+ .extra-info {
+ // header title should not be centered if there's no tags / categories
+ &:not(.two-rows) {
+ min-height: 2.75em;
+ }
+ h1 {
+ margin: 0 0 0.125em 0;
+ }
}
}
@@ -41,11 +46,3 @@
color: dark-light-choose($primary-high, $secondary-low);
}
}
-
-header {
- #site-text-logo {
- font-size: $font-up-3;
- margin-top: 0.4em;
- line-height: $line-height-medium;
- }
-}
diff --git a/app/assets/stylesheets/desktop/topic-post.scss b/app/assets/stylesheets/desktop/topic-post.scss
index cb9dafa3d1f..b81211e5baf 100644
--- a/app/assets/stylesheets/desktop/topic-post.scss
+++ b/app/assets/stylesheets/desktop/topic-post.scss
@@ -11,14 +11,6 @@ h1 .topic-statuses .topic-status i {
vertical-align: middle;
}
-.logo-small {
- margin-right: 8px;
- width: auto;
- max-width: 80px;
- height: auto;
- max-height: 40px;
-}
-
.topic-body {
padding: 0;
&:first-of-type {
@@ -506,64 +498,6 @@ video {
}
}
-.extra-info-wrapper {
- overflow: hidden;
- .badge-wrapper,
- i,
- .topic-link {
- -webkit-animation: fadein 0.7s;
- animation: fadein 0.7s;
- }
- .topic-statuses {
- i {
- color: $header_primary;
- }
- .d-icon-envelope {
- color: $danger;
- }
- .d-icon-lock {
- padding-top: 0.15em;
- }
- .unpinned {
- color: $header_primary;
- }
- }
- .topic-link {
- color: $header_primary;
- display: block;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .topic-header-extra {
- margin: 0 0 0 5px;
- }
-}
-
-/* default docked header CSS for all topics, including those without categories */
-
-.extra-info {
- h1 {
- margin: 5px 0 0 0;
- font-size: $font-up-3;
- line-height: $line-height-large;
- width: 100%;
- }
- .topic-statuses {
- margin-top: -2px;
- }
-}
-
-/* override docked header CSS for topics with categories */
-
-.extra-info.two-rows {
- h1 {
- line-height: $line-height-medium;
- margin: 0;
- width: 100%;
- }
-}
-
.open > .dropdown-menu {
display: block;
}
diff --git a/app/assets/stylesheets/mobile/discourse.scss b/app/assets/stylesheets/mobile/discourse.scss
index e211ebc25b7..ce37c2393d2 100644
--- a/app/assets/stylesheets/mobile/discourse.scss
+++ b/app/assets/stylesheets/mobile/discourse.scss
@@ -149,9 +149,3 @@ blockquote {
#simple-container {
width: 90%;
}
-
-// somehow the image logo assumption inherits margins from earlier in the CSS
-// stack we must remove margins for text site titles
-h1#site-text-logo {
- margin: 0 0 0 10px;
-}
diff --git a/app/assets/stylesheets/mobile/header.scss b/app/assets/stylesheets/mobile/header.scss
index e4d2abb9040..49971d56da1 100644
--- a/app/assets/stylesheets/mobile/header.scss
+++ b/app/assets/stylesheets/mobile/header.scss
@@ -2,37 +2,50 @@
// Discourse header
// --------------------------------------------------
-#site-text-logo {
- font-size: $font-up-3;
-}
-@include breakpoint(mobile-small) {
- #site-text-logo {
- font-size: $font-up-2;
- }
-}
-
.d-header {
- #site-logo {
- max-width: 8.8em;
- }
+ height: 3.66em;
// some protection for text-only site titles
.title {
- max-width: 50%;
- height: 39px;
+ max-width: 75%;
+ white-space: nowrap;
overflow: hidden;
- padding: 0;
- text-overflow: clip;
- display: table;
+ text-overflow: ellipsis;
+ -webkit-animation: fadein 0.5s;
+ animation: fadein 0.5s;
a {
- display: table-cell;
- vertical-align: middle;
+ display: block;
+ }
+ }
+ #site-text-logo {
+ margin: 0;
+ font-size: $font-up-1;
+ }
+ .extra-info-wrapper {
+ .extra-info {
+ // header title should not be centered if there's no tags / categories
+ &:not(.two-rows) {
+ min-height: 2.25em;
+ }
+ h1 {
+ font-size: $font-0;
+ }
+ .private-message-glyph-wrapper {
+ float: left;
+ }
}
}
-
button.sign-up-button {
display: none;
}
+ // styles for mobile scroll logo / topic
+ .panel {
+ -webkit-animation: fadein 0.5s;
+ animation: fadein 0.5s;
+ }
+ &.scroll-down .panel {
+ display: none;
+ }
}
.d-header-icons {
diff --git a/app/assets/stylesheets/mobile/topic-post.scss b/app/assets/stylesheets/mobile/topic-post.scss
index 802bc5802d1..6d65d3be04f 100644
--- a/app/assets/stylesheets/mobile/topic-post.scss
+++ b/app/assets/stylesheets/mobile/topic-post.scss
@@ -1,5 +1,4 @@
/* hide the reply border above the time gap notices */
-
.time-gap + .topic-post article {
border-top: none;
}
@@ -319,10 +318,6 @@ iframe {
max-width: 100%;
}
-.extra-info {
- display: none;
-}
-
.open > .dropdown-menu {
display: block;
}