-{{/if}}
\ No newline at end of file
+{{/if}}
diff --git a/app/assets/javascripts/discourse/templates/components/user-card-contents.hbs b/app/assets/javascripts/discourse/templates/components/user-card-contents.hbs
index 7242b76aa0f..d2b2e096c56 100644
--- a/app/assets/javascripts/discourse/templates/components/user-card-contents.hbs
+++ b/app/assets/javascripts/discourse/templates/components/user-card-contents.hbs
@@ -3,7 +3,7 @@
-
{{bound-avatar user "huge"}}
+
{{bound-avatar user "huge"}}
{{#if user.primary_group_name}}
{{avatar-flair
flairURL=user.primary_group_flair_url
@@ -16,10 +16,12 @@
- {{plugin-outlet name="user-card-after-username" args=(hash user=user showUser=(action "showUser")) tagName=''}}
+ {{plugin-outlet name="user-card-after-username" args=(hash user=user showUser=(action "showUser" user)) tagName=''}}
{{#unless nameFirst}}
{{#if user.name}}
{{user.name}}
@@ -188,9 +190,11 @@
{{user-badge badge=ub.badge user=user}}
{{/each}}
{{#if showMoreBadges}}
- {{#link-to 'user.badges' user class="user-badge more-user-badges"}}
- {{i18n 'badges.more_badges' count=moreBadgesCount}}
- {{/link-to}}
+
+ {{#link-to 'user.badges' user}}
+ {{i18n 'badges.more_badges' count=moreBadgesCount}}
+ {{/link-to}}
+
{{/if}}
{{/if}}
@@ -198,4 +202,4 @@
{{/if}}
-{{/if}}
\ No newline at end of file
+{{/if}}
diff --git a/app/assets/javascripts/discourse/templates/mobile/list/topic-list-item.raw.hbs b/app/assets/javascripts/discourse/templates/mobile/list/topic-list-item.raw.hbs
index 7333de7d55a..baef9931645 100644
--- a/app/assets/javascripts/discourse/templates/mobile/list/topic-list-item.raw.hbs
+++ b/app/assets/javascripts/discourse/templates/mobile/list/topic-list-item.raw.hbs
@@ -1,47 +1,44 @@
{{~#unless expandPinned}}
- {{else}}
-
- {{/unless~}}
-
- {{~raw-plugin-outlet name="topic-list-before-status"}}
- {{~raw "topic-status" topic=topic~}}
- {{~topic-link topic~}}
- {{~#if topic.featured_link~}}
- {{~topic-featured-link topic~}}
- {{~/if~}}
- {{~#if topic.unseen~}}
-
- {{~/if~}}
- {{~#if expandPinned~}}
- {{~raw "list/topic-excerpt" topic=topic~}}
- {{~/if~}}
-
-
-
- {{raw "list/post-count-or-badges" topic=topic postBadgesEnabled=showTopicPostBadges}}
-
-
-
- {{#unless hideCategory}}
-
- {{category-link topic.category}}
+ {{else}}
+
+ {{/unless~}}
+
+ {{~raw-plugin-outlet name="topic-list-before-status"}}
+ {{~raw "topic-status" topic=topic~}}
+ {{~topic-link topic~}}
+ {{~#if topic.featured_link~}}
+ {{~topic-featured-link topic~}}
+ {{~/if~}}
+ {{~#if topic.unseen~}}
+
+ {{~/if~}}
+ {{~#if expandPinned~}}
+ {{~raw "list/topic-excerpt" topic=topic~}}
+ {{~/if~}}
- {{/unless}}
-
- {{discourse-tags topic mode="list"}}
-
-
-
- |
+
\ No newline at end of file
diff --git a/app/assets/javascripts/discourse/templates/user-card.hbs b/app/assets/javascripts/discourse/templates/user-card.hbs
index b7e2924e17c..f88e2aa21eb 100644
--- a/app/assets/javascripts/discourse/templates/user-card.hbs
+++ b/app/assets/javascripts/discourse/templates/user-card.hbs
@@ -1,3 +1,7 @@
+{{#if site.mobileView}}
+
+{{/if}}
+
{{user-card-contents
currentPath=application.currentPath
topic=topic.model
@@ -9,4 +13,5 @@
currentPath=application.currentPath
topic=topic.model
showUser=(action "showUser")
+ showGroup=(action "showGroup")
createNewMessageViaParams=(route-action "createNewMessageViaParams")}}
diff --git a/app/assets/stylesheets/desktop/user-card.scss b/app/assets/stylesheets/common/components/user-card.scss
similarity index 77%
rename from app/assets/stylesheets/desktop/user-card.scss
rename to app/assets/stylesheets/common/components/user-card.scss
index e294a1cde7d..27f5226a2c5 100644
--- a/app/assets/stylesheets/desktop/user-card.scss
+++ b/app/assets/stylesheets/common/components/user-card.scss
@@ -5,14 +5,11 @@ $avatar_margin: -50px; // negative margin makes avatars extend above cards
// shared styles for user and group cards
#user-card,
#group-card {
- position: absolute;
width: $card_width;
- z-index: z("usercard");
box-shadow: shadow("card");
color: $primary;
background: $secondary center center;
background-size: cover;
- min-height: 175px;
transition: opacity 0.2s, transform 0.2s;
-webkit-transition: opacity 0.2s, -webkit-transform 0.2s;
opacity: 0;
@@ -21,17 +18,8 @@ $avatar_margin: -50px; // negative margin makes avatars extend above cards
opacity: 1;
@include transform(scale(1));
}
- &.fixed {
- position: fixed;
- z-index: z("composer", "content") + 1;
- }
-
- &.docked-card {
- z-index: z("header") + 1;
- }
-
.card-content {
- padding: 12px;
+ padding: 10px;
background: rgba($secondary, 0.85);
margin-top: 80px;
&:after {
@@ -44,74 +32,71 @@ $avatar_margin: -50px; // negative margin makes avatars extend above cards
}
}
&.no-bg {
- min-height: 50px;
.card-content {
margin-top: 0;
}
}
- .names {
- flex: 1 1 auto;
- margin-left: 0.75em;
- span {
- display: block;
+ .card-row:not(.first-row) {
+ margin-top: 0.5em;
+ }
+ // avatar - names - controls
+ .first-row {
+ .names {
+ padding-left: 1.25em;
+ span {
+ display: block;
+ }
}
+ .usercard-controls {
+ list-style-type: none;
+ margin: 0;
+ button {
+ width: 100%;
+ }
+ }
+ }
+ .btn {
+ margin-bottom: 5px;
}
h1 {
- margin: 0;
line-height: $line-height-medium;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- a {
- color: $primary;
- }
.d-icon {
- font-size: $font-down-1;
- color: $primary;
- }
- }
- h2 {
- font-size: $font-up-1;
- margin: 0;
- font-weight: normal;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- a {
color: $primary;
}
}
h3 {
display: inline;
margin-right: 0.5em;
- font-size: $font-0;
- font-weight: normal;
color: $primary;
.desc,
a {
color: $primary-high;
}
}
+ h1,
+ h2,
+ h3 {
+ margin: 0;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+ h1,
+ h2 {
+ a {
+ color: $primary;
+ }
+ }
+ h2,
+ h3 {
+ font-weight: normal;
+ }
p {
margin: 0 0 5px 0;
}
- .btn {
- margin-bottom: 5px;
- }
- .usercard-controls {
- list-style-type: none;
- margin: 0;
- button {
- width: 100%;
- min-width: 150px;
- }
- }
- .card-row:not(.first-row) {
- margin-top: 0.5em;
- }
}
-// styles for user cards
+// styles for user cards only
#user-card {
// avatar - names - controls
.first-row {
@@ -121,7 +106,6 @@ $avatar_margin: -50px; // negative margin makes avatars extend above cards
height: $avatar_width;
}
.user-card-avatar {
- margin-right: 10px;
margin-top: $avatar_margin;
}
.new-user a {
@@ -196,9 +180,9 @@ $avatar_margin: -50px; // negative margin makes avatars extend above cards
display: flex;
align-items: flex-start;
.user-badge {
- display: flex;
white-space: nowrap;
- margin: 0 0.5em 0 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
background: $primary-very-low;
border: 1px solid $primary-low;
color: $primary;
@@ -206,16 +190,17 @@ $avatar_margin: -50px; // negative margin makes avatars extend above cards
.badge-display-name {
overflow: hidden;
text-overflow: ellipsis;
- max-width: 185px;
}
.more-user-badges {
- overflow: hidden;
+ a {
+ @extend .user-badge;
+ }
}
}
}
}
-// styles for group cards
+// styles for group cards only
#group-card {
// avatar - names and controls
.first-row {
@@ -223,19 +208,18 @@ $avatar_margin: -50px; // negative margin makes avatars extend above cards
.group-card-avatar {
margin-top: $avatar_margin;
}
- .group-card-avatar {
- .avatar-flair {
- width: $avatar_width;
- height: $avatar_width;
- display: flex;
- color: $primary;
- .d-icon {
- margin: auto;
- font-size: $avatar_width / 1.5;
- }
- &.rounded {
- border-radius: 50%;
- }
+ .avatar-flair {
+ display: flex;
+ background-size: contain;
+ width: $avatar_width;
+ height: $avatar_width;
+ color: $primary;
+ .d-icon {
+ margin: auto;
+ font-size: $avatar_width / 1.5;
+ }
+ &.rounded {
+ border-radius: 50%;
}
}
}
diff --git a/app/assets/stylesheets/desktop.scss b/app/assets/stylesheets/desktop.scss
index 1769f2ee60b..4e4a7e4cbd6 100644
--- a/app/assets/stylesheets/desktop.scss
+++ b/app/assets/stylesheets/desktop.scss
@@ -9,7 +9,6 @@
@import "desktop/header";
@import "desktop/login";
@import "desktop/modal";
-@import "desktop/user-card";
@import "desktop/category-list";
@import "desktop/latest-topic-list";
@import "desktop/topic-list";
diff --git a/app/assets/stylesheets/desktop/components/user-card.scss b/app/assets/stylesheets/desktop/components/user-card.scss
new file mode 100644
index 00000000000..7bc2b0aea1d
--- /dev/null
+++ b/app/assets/stylesheets/desktop/components/user-card.scss
@@ -0,0 +1,52 @@
+// shared styles for user and group cards
+#user-card,
+#group-card {
+ position: absolute;
+ z-index: z("usercard");
+ &.fixed {
+ position: fixed;
+ z-index: z("composer", "content") + 1;
+ }
+ &.docked-card {
+ z-index: z("header") + 1;
+ }
+ // avatar - names - controls
+ .first-row {
+ .names {
+ flex: 1 1 auto;
+ }
+ .usercard-controls {
+ button {
+ min-width: 150px;
+ }
+ }
+ }
+ h1 {
+ .d-icon {
+ font-size: $font-down-1;
+ }
+ }
+ h2 {
+ font-size: $font-up-1;
+ }
+ h3 {
+ font-size: $font-0;
+ }
+}
+
+// styles for user cards only
+#user-card {
+ // badges
+ .sixth-row {
+ .badge-section {
+ .user-badge {
+ display: block;
+ max-width: 185px;
+ margin: 0 0.5em 0 0;
+ }
+ .more-user-badges {
+ max-width: 125px;
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/mobile/components/user-card.scss b/app/assets/stylesheets/mobile/components/user-card.scss
new file mode 100644
index 00000000000..fcd0969d08d
--- /dev/null
+++ b/app/assets/stylesheets/mobile/components/user-card.scss
@@ -0,0 +1,88 @@
+$avatar_width: 120px;
+
+// shared styles for user and group cards
+#user-card,
+#group-card {
+ position: fixed;
+ // mobile cards should always be on top of everything - 1102
+ z-index: z("mobile-composer") + 2;
+ max-width: 95vw;
+ margin: 0 2.5vw;
+ max-height: 90vh;
+ // avatar - names - controls
+ .first-row {
+ flex-wrap: wrap;
+ .names {
+ flex: 1 1 calc(100% - #{$avatar_width});
+ box-sizing: border-box;
+ }
+ .usercard-controls {
+ display: flex;
+ flex: 1;
+ margin-top: 1em;
+ button {
+ white-space: nowrap;
+ }
+ li {
+ flex: 1;
+ & + li {
+ margin-left: 0.5em;
+ }
+ }
+ }
+ }
+ h1 {
+ font-size: $font-up-3;
+ .d-icon {
+ font-size: $font-down-2;
+ }
+ }
+ h2 {
+ font-size: $font-0;
+ }
+ h3 {
+ font-size: $font-down-1;
+ }
+}
+
+// styles for user cards only
+#user-card {
+ // badges
+ .sixth-row {
+ .badge-section {
+ flex-wrap: wrap;
+ > span {
+ display: flex;
+ flex: 0 1 50%;
+ max-width: 50%; // for text ellipsis
+ padding: 2px 0;
+ box-sizing: border-box;
+ &:nth-of-type(1),
+ &:nth-of-type(3) {
+ padding-right: 4px;
+ }
+ a {
+ width: 100%;
+ display: flex;
+ }
+ }
+ .user-badge {
+ display: flex;
+ margin: 0;
+ width: 100%;
+ }
+ }
+ }
+}
+
+// mobile card cloak
+.card-cloak {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: z("mobile-composer") + 1; // 1101
+ height: 100vh;
+ width: 100vw;
+ background-color: rgba(black, 0.5);
+ animation: fadein 0.2s;
+}
diff --git a/app/assets/stylesheets/mobile/discourse.scss b/app/assets/stylesheets/mobile/discourse.scss
index 8b833ca45a1..d7f07da4011 100644
--- a/app/assets/stylesheets/mobile/discourse.scss
+++ b/app/assets/stylesheets/mobile/discourse.scss
@@ -132,3 +132,17 @@ blockquote {
#simple-container {
width: 90%;
}
+
+// this is used to provide visual feedback that indicates that the user / group
+// cards are loading after the user clicks on an avatar. It's mostly for very slow
+// connections. Users on good connections won't notice it.
+[data-user-card]:focus {
+ .avatar,
+ + .avatar-flair {
+ animation: wave 0.75s infinite;
+ animation-delay: 0.5s;
+ }
+ .avatar {
+ position: relative;
+ }
+}
diff --git a/script/benchmarks/markdown/giant_post.md b/script/benchmarks/markdown/giant_post.md
index 3da15173e4c..fe3f3ee4d08 100644
--- a/script/benchmarks/markdown/giant_post.md
+++ b/script/benchmarks/markdown/giant_post.md
@@ -137,7 +137,6 @@
app/assets/stylesheets/desktop/topic-post.scss | 8 +-
app/assets/stylesheets/desktop/topic.scss | 5 +-
app/assets/stylesheets/desktop/upload.scss | 2 +-
- app/assets/stylesheets/desktop/user-card.scss | 2 +-
app/assets/stylesheets/desktop/user.scss | 8 -
app/assets/stylesheets/mobile.scss | 1 +
app/assets/stylesheets/mobile/alert.scss | 2 +
diff --git a/test/javascripts/acceptance/group-card-mobile-test.js.es6 b/test/javascripts/acceptance/group-card-mobile-test.js.es6
index 9b353c8a085..4d3e2adeb3c 100644
--- a/test/javascripts/acceptance/group-card-mobile-test.js.es6
+++ b/test/javascripts/acceptance/group-card-mobile-test.js.es6
@@ -1,11 +1,22 @@
import { acceptance } from "helpers/qunit-helpers";
+import DiscourseURL from "discourse/lib/url";
acceptance("Group Card - Mobile", { mobileView: true });
QUnit.test("group card", async assert => {
await visit("/t/301/1");
- assert.ok(invisible("#group-card"), "user card is invisible by default");
+ assert.ok(
+ invisible("#group-card"),
+ "mobile group card is invisible by default"
+ );
await click("a.mention-group:first");
- assert.ok(visible(".group-details-container"), "group page should be shown");
+ assert.ok(visible("#group-card"), "mobile group card should appear");
+
+ sandbox.stub(DiscourseURL, "routeTo");
+ await click(".card-content a.group-page-link");
+ assert.ok(
+ DiscourseURL.routeTo.calledWith("/g/discourse"),
+ "it should navigate to the group page"
+ );
});
diff --git a/test/javascripts/acceptance/group-card-test.js.es6 b/test/javascripts/acceptance/group-card-test.js.es6
index 2b8496936c1..e64a86baa00 100644
--- a/test/javascripts/acceptance/group-card-test.js.es6
+++ b/test/javascripts/acceptance/group-card-test.js.es6
@@ -1,4 +1,5 @@
import { acceptance } from "helpers/qunit-helpers";
+import DiscourseURL from "discourse/lib/url";
acceptance("Group Card");
@@ -8,4 +9,11 @@ QUnit.test("group card", async assert => {
await click("a.mention-group:first");
assert.ok(visible("#group-card"), "card should appear");
+
+ sandbox.stub(DiscourseURL, "routeTo");
+ await click(".card-content a.group-page-link");
+ assert.ok(
+ DiscourseURL.routeTo.calledWith("/g/discourse"),
+ "it should navigate to the group page"
+ );
});
diff --git a/test/javascripts/acceptance/user-card-mobile-test.js.es6 b/test/javascripts/acceptance/user-card-mobile-test.js.es6
new file mode 100644
index 00000000000..2bc41d2d921
--- /dev/null
+++ b/test/javascripts/acceptance/user-card-mobile-test.js.es6
@@ -0,0 +1,22 @@
+import { acceptance } from "helpers/qunit-helpers";
+import DiscourseURL from "discourse/lib/url";
+
+acceptance("User Card - Mobile", { mobileView: true });
+
+QUnit.test("user card", async assert => {
+ await visit("/t/internationalization-localization/280");
+ assert.ok(
+ invisible("#user-card"),
+ "mobile user card is invisible by default"
+ );
+
+ await click("a[data-user-card=eviltrout]:first");
+ assert.ok(visible("#user-card"), "mobile user card should appear");
+
+ sandbox.stub(DiscourseURL, "routeTo");
+ await click(".card-content a.user-profile-link");
+ assert.ok(
+ DiscourseURL.routeTo.calledWith("/u/eviltrout"),
+ "it should navigate to the user profile"
+ );
+});
diff --git a/test/javascripts/acceptance/user-card-test.js.es6 b/test/javascripts/acceptance/user-card-test.js.es6
index 30d163b3ed5..f4819f06ea7 100644
--- a/test/javascripts/acceptance/user-card-test.js.es6
+++ b/test/javascripts/acceptance/user-card-test.js.es6
@@ -4,13 +4,16 @@ import DiscourseURL from "discourse/lib/url";
acceptance("User Card");
QUnit.test("user card", async assert => {
- await visit("/");
+ await visit("/t/internationalization-localization/280");
assert.ok(invisible("#user-card"), "user card is invisible by default");
await click("a[data-user-card=eviltrout]:first");
assert.ok(visible("#user-card"), "card should appear");
sandbox.stub(DiscourseURL, "routeTo");
- await click(".card-content a.mention");
- assert.ok(DiscourseURL.routeTo.calledWith("/u/eviltrout"));
+ await click(".card-content a.user-profile-link");
+ assert.ok(
+ DiscourseURL.routeTo.calledWith("/u/eviltrout"),
+ "it should navigate to the user profile"
+ );
});