Commit 268571c4 authored by Jon Parsons's avatar Jon Parsons Committed by Andrew Newdigate

Merge branch 'feature/topics-buttons' into feature/mobile-fixes-for-topic-view

parents 9601b3b0 5b3ec0b6
......@@ -13,6 +13,7 @@
//TODO Remove this
@editable-content-editor-border: #eee;
@forum-subscribe-area-border: #eee;
//Forum specific
@topic-table-bg: @light;
......
......@@ -15,16 +15,6 @@
cursor: pointer;
padding: 0;
&:after {
content: ' ';
background-repeat: no-repeat;
background-size: cover;
}
}
.icon-button-like {
.icon-button();
font-size: 1.35rem;
text-transform: uppercase;
font-family: @font-family;
......@@ -32,7 +22,10 @@
padding-right: 1rem;
&:after {
&:extend(.icon-like);
content: '';
background-repeat: no-repeat;
background-size: contain;
display: inline-block;
width: @icon-size;
height: @icon-size;
......@@ -40,29 +33,34 @@
}
}
.icon-button-like {
.icon-button();
&:after { &:extend(.icon-like); }
}
.icon-button-like-selected {
.icon-button-like();
color: @dark;
.icon-button();
color: @caribbean;
&:after { &:extend(.icon-like-selected); }
}
.icon-button-comment {
.icon-button-like();
.icon-button();
&:after { &:extend(.icon-comments); }
}
.icon-button-edit {
.icon-button-like();
.icon-button();
&:after { &:extend(.icon-edit); }
&:hover { &:after { &:extend(.icon-edit-selected); } }
}
.icon-button-watch {
.icon-button-like();
.icon-button();
&:after { &:extend(.icon-watch); }
}
.icon-button-watch-selected {
.icon-button-like();
&:after { &:extend(.icons-watch-selected); }
.icon-button();
&:after { &:extend(.icon-watch-selected); }
}
@import (less, reference) "~gitter-styleguide/css/components/buttons.css";
@import "../../icons";
.m-forum-follow-button () {
&:extend(.secondary-button-jaffa--small all);
display: flex;
align-items: center;
padding: .5rem 1rem;
cursor: pointer;
}
.m-pseudo-icon {
content: ' ';
display: inline-block;
height: 2rem;
width: 2rem;
margin-right: .5rem;
}
.follow-button--subscribed {
.m-forum-follow-button();
&:before {
&:extend(.icon-unwatch-jaffa);
.m-pseudo-icon();
}
}
.follow-button--unsubscribed {
.m-forum-follow-button();
&:before {
&:extend(.icon-watch-jaffa);
.m-pseudo-icon();
}
}
......@@ -12,7 +12,7 @@
.topics-table-header__cell {
&:extend(.h5);
padding: 4rem 1rem 1rem;
padding: 2rem 1rem 1rem;
text-align: center;
text-transform: uppercase;
......
......@@ -65,3 +65,11 @@
background-color: @topic-reply-list-header-bg;
@media @only-small { padding: 2rem; }
}
.panel--forum-follow-area {
background-color: @light;
border-bottom: 1px solid @forum-subscribe-area-border;
padding: (@panel-vert-padding / 2) @panel-horiz-padding;
@media @only-small { padding: 1rem; }
}
@import "../../colors.less";
@import (less, reference) "~gitter-styleguide/css/components/headings.css";
@import (less, reference) "~gitter-styleguide/css/components/buttons.css";
@import "../../colors.less";
@import "../../text";
@import "../../break-points";
......
......@@ -4,5 +4,7 @@
.icon-comments-selected { background-image: url('../svg/comments-selected.svg'); }
.icon-edit { background-image: url('../svg/edit.svg'); }
.icon-edit-selected { background-image: url('../svg/edit-selected.svg'); }
.icons-watch { background-image: url('../svg/watch.svg'); }
.icons-watch-selected { background-image: url('../svg/watch-selected.svg'); }
.icon-watch { background-image: url('../svg/watch.svg'); }
.icon-watch-selected { background-image: url('../svg/watch-selected.svg'); }
.icon-watch-jaffa { background-image: url('../svg/watch-jaffa.svg'); }
.icon-unwatch-jaffa { background-image: url('../svg/unwatch-jaffa.svg'); }
......@@ -71,6 +71,7 @@ body {
@import "./components/forum/topics-table-header";
@import "./components/forum/topics-table-body";
@import "./components/forum/reaction-button";
@import "./components/forum/forum-follow-button";
//Topics specific
@import "./components/topic/create-topic-modal";
......
......@@ -3,22 +3,22 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#676767;}
.st0{fill:#46BC99;}
</style>
<g>
<path class="st0" d="M14.6,7.4c0,0.5-0.1,1-0.4,1.4c0.1,0.2,0.1,0.4,0.1,0.6c0,0.4-0.1,0.8-0.3,1.2c0,0.1,0,0.2,0,0.4
c0,0.6-0.2,1.1-0.5,1.5c0,0.8-0.2,1.4-0.7,1.9c-0.5,0.5-1.1,0.7-1.9,0.7h-0.3H9.6c-0.5,0-1.1-0.1-1.6-0.2c-0.5-0.1-1.2-0.3-1.9-0.6
C5.5,14.1,5.1,14,5,14H2.5c-0.3,0-0.6-0.1-0.8-0.3c-0.2-0.2-0.3-0.5-0.3-0.8V7.5c0-0.3,0.1-0.6,0.3-0.8C2,6.5,2.2,6.4,2.5,6.4h2.3
C5.1,6.2,5.5,5.8,6,5C6.4,4.6,6.7,4.2,7,3.9c0.1-0.1,0.2-0.4,0.3-0.7s0.2-0.7,0.3-1.1c0.1-0.4,0.3-0.7,0.5-0.9
C8.3,1,8.5,0.9,8.8,0.9c0.5,0,0.9,0.1,1.3,0.3C10.5,1.3,10.8,1.6,11,2s0.3,0.9,0.3,1.6c0,0.5-0.1,1.1-0.4,1.6h1.5
c0.6,0,1.1,0.2,1.5,0.7C14.4,6.3,14.6,6.9,14.6,7.4z M3.5,12.8c0.1-0.1,0.2-0.2,0.2-0.4c0-0.1-0.1-0.3-0.2-0.4
c-0.1-0.1-0.2-0.2-0.4-0.2c-0.1,0-0.3,0.1-0.4,0.2c-0.1,0.1-0.2,0.2-0.2,0.4c0,0.1,0.1,0.3,0.2,0.4c0.1,0.1,0.2,0.2,0.4,0.2
C3.2,12.9,3.3,12.9,3.5,12.8z M13.5,7.5c0-0.3-0.1-0.5-0.3-0.8c-0.2-0.2-0.5-0.3-0.8-0.3h-3C9.4,6,9.5,5.6,9.8,5s0.4-1,0.4-1.4
c0-0.6-0.1-1-0.3-1.2C9.7,2.1,9.4,2,8.8,2C8.7,2.1,8.6,2.4,8.5,2.7C8.4,3,8.3,3.4,8.2,3.8C8.1,4.2,8,4.5,7.7,4.7
C7.6,4.8,7.4,5.1,7.1,5.5c0,0-0.1,0.1-0.2,0.3C6.8,5.9,6.7,6,6.6,6.1C6.5,6.2,6.4,6.3,6.3,6.5C6.2,6.6,6.1,6.7,6,6.8
C5.9,6.9,5.8,7,5.6,7.1C5.5,7.2,5.4,7.3,5.3,7.4C5.2,7.4,5.1,7.5,5,7.5H4.7v5.5H5c0.1,0,0.2,0,0.3,0c0.1,0,0.2,0,0.3,0.1
c0.1,0,0.2,0.1,0.3,0.1c0.1,0,0.2,0.1,0.3,0.1s0.2,0.1,0.3,0.1c0.1,0,0.2,0.1,0.2,0.1C7.9,13.8,8.9,14,9.6,14h1
c1.1,0,1.6-0.5,1.6-1.4c0-0.1,0-0.3,0-0.5c0.2-0.1,0.3-0.2,0.4-0.4c0.1-0.2,0.1-0.4,0.1-0.6s-0.1-0.4-0.2-0.6
c0.3-0.3,0.5-0.6,0.5-1c0-0.1,0-0.3-0.1-0.5c-0.1-0.2-0.1-0.3-0.2-0.4c0.2,0,0.3-0.1,0.5-0.4C13.4,7.9,13.5,7.7,13.5,7.5z"/>
<path class="st0" d="M14.5,7.4c0,0.5-0.1,1-0.4,1.4c0.1,0.2,0.1,0.4,0.1,0.6c0,0.4-0.1,0.9-0.3,1.2c0,0.1,0,0.2,0,0.4
c0,0.6-0.2,1.1-0.5,1.5c0,0.8-0.2,1.4-0.7,1.9c-0.5,0.5-1.1,0.7-2,0.7h-0.3H9.6c-0.6,0-1.1-0.1-1.6-0.2c-0.5-0.1-1.2-0.3-1.9-0.6
C5.4,14.1,5,14,4.9,14H2.4c-0.3,0-0.6-0.1-0.8-0.3s-0.3-0.5-0.3-0.8V7.4c0-0.3,0.1-0.6,0.3-0.8s0.5-0.3,0.8-0.3h2.4
C5,6.1,5.4,5.7,5.9,4.9c0.3-0.4,0.6-0.8,0.9-1.1C7,3.7,7.1,3.4,7.2,3.1C7.2,2.8,7.3,2.4,7.4,2C7.5,1.6,7.7,1.3,8,1.1
c0.2-0.2,0.5-0.3,0.8-0.3C9.2,0.8,9.7,0.9,10,1s0.7,0.5,0.9,0.9s0.3,0.9,0.3,1.6c0,0.5-0.1,1.1-0.4,1.7h1.5c0.6,0,1.1,0.2,1.6,0.7
S14.5,6.8,14.5,7.4z M3.3,12.7c0.1-0.1,0.2-0.2,0.2-0.4S3.5,12.1,3.3,12c-0.1-0.1-0.2-0.2-0.4-0.2S2.7,11.8,2.6,12
c-0.1,0.1-0.2,0.2-0.2,0.4s0.1,0.3,0.2,0.4c0.1,0.1,0.2,0.2,0.4,0.2S3.2,12.8,3.3,12.7z M13.4,7.4c0-0.3-0.1-0.6-0.3-0.8
c-0.2-0.2-0.5-0.3-0.8-0.3h-3c0-0.3,0.1-0.8,0.4-1.4c0.3-0.6,0.4-1,0.4-1.4c0-0.6-0.1-1-0.3-1.2C9.7,2,9.3,1.9,8.7,1.9
C8.6,2,8.5,2.3,8.4,2.6S8.3,3.3,8.2,3.7C8.1,4.1,7.9,4.4,7.6,4.6C7.5,4.8,7.3,5,7,5.4c0,0-0.1,0.1-0.2,0.3C6.7,5.8,6.6,5.9,6.5,6
S6.3,6.2,6.2,6.4S6,6.7,5.9,6.8S5.7,7,5.5,7.1S5.3,7.3,5.2,7.3C5.1,7.4,5,7.4,4.9,7.4H4.6v5.5h0.3c0.1,0,0.2,0,0.3,0
c0.1,0,0.2,0,0.3,0.1c0.1,0,0.2,0.1,0.3,0.1c0.1,0,0.2,0.1,0.3,0.1c0.1,0,0.2,0.1,0.3,0.1c0.1,0,0.2,0.1,0.2,0.1
C7.8,13.8,8.8,14,9.6,14h1c1.1,0,1.7-0.5,1.7-1.4c0-0.1,0-0.3,0-0.5c0.2-0.1,0.3-0.2,0.4-0.5c0.1-0.2,0.2-0.4,0.2-0.6
c0-0.2-0.1-0.4-0.2-0.6c0.3-0.3,0.5-0.6,0.5-1c0-0.1,0-0.3-0.1-0.5c-0.1-0.2-0.1-0.3-0.2-0.4c0.2,0,0.3-0.1,0.5-0.4
C13.4,7.8,13.4,7.6,13.4,7.4z"/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 20.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F68D42;}
</style>
<g>
<path class="st0" d="M11.6,3.1C11.6,3.1,11.6,3.1,11.6,3.1C11,4.2,10,5.9,8.8,8c-1.2,2.2-2.1,3.8-2.7,4.9l-0.4,0.8
c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0-0.5-0.2-1.2-0.6c-0.1-0.1-0.1-0.1-0.1-0.2c0-0.1,0.1-0.3,0.4-0.8c-0.8-0.4-1.6-0.9-2.3-1.5
C1.6,10.1,1,9.4,0.5,8.6C0.4,8.5,0.3,8.3,0.3,8c0-0.2,0.1-0.4,0.2-0.6c0.9-1.3,2-2.4,3.3-3.2C5.1,3.5,6.5,3.1,8,3.1
c0.5,0,1,0,1.6,0.1L10,2.4c0.1-0.1,0.1-0.1,0.2-0.1c0,0,0.1,0,0.2,0.1c0.1,0,0.2,0.1,0.3,0.1s0.2,0.1,0.3,0.2
c0.1,0.1,0.2,0.1,0.3,0.2c0.1,0.1,0.2,0.1,0.2,0.1C11.5,2.9,11.6,3,11.6,3.1z M5.1,11.3l0.7-1.2C5.3,9.7,4.9,9.2,4.6,8.7
C4.3,8.1,4.2,7.5,4.2,6.9c0-0.7,0.2-1.3,0.5-1.9C3.4,5.7,2.3,6.7,1.4,8C2.4,9.5,3.6,10.6,5.1,11.3z M8.3,5c0.1-0.1,0.1-0.2,0.1-0.3
s0-0.2-0.1-0.3C8.2,4.4,8.1,4.3,8,4.3c-0.7,0-1.3,0.3-1.8,0.8C5.7,5.6,5.4,6.2,5.4,6.9c0,0.1,0,0.2,0.1,0.3
c0.1,0.1,0.2,0.1,0.3,0.1c0.1,0,0.2,0,0.3-0.1C6.2,7.1,6.2,7,6.2,6.9c0-0.5,0.2-0.9,0.5-1.3C7.1,5.3,7.5,5.1,8,5.1
C8.1,5.1,8.2,5.1,8.3,5z M15.7,8c0,0.2-0.1,0.4-0.2,0.6C15.3,9,15,9.4,14.6,9.9c-0.9,1-1.9,1.8-3,2.3S9.3,13,8,13l0.6-1.1
c1.2-0.1,2.3-0.5,3.4-1.2s1.9-1.6,2.6-2.6c-0.7-1-1.5-1.9-2.4-2.5l0.5-1c0.5,0.4,1.1,0.8,1.6,1.3c0.5,0.5,0.9,1,1.2,1.6
C15.7,7.6,15.7,7.8,15.7,8z M11.9,6.9c0,0.8-0.2,1.5-0.7,2.2s-1.1,1.1-1.8,1.4l2.4-4.3C11.9,6.5,11.9,6.7,11.9,6.9z"/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 20.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F68D42;}
</style>
<g>
<path class="st0" d="M15.7,8c0,0.2-0.1,0.4-0.2,0.6c-0.8,1.3-1.9,2.4-3.2,3.2S9.5,13,8,13s-2.9-0.4-4.3-1.2S1.3,9.9,0.5,8.6
C0.4,8.4,0.3,8.2,0.3,8c0-0.2,0.1-0.4,0.2-0.6C1.3,6.1,2.4,5,3.7,4.3S6.5,3.1,8,3.1s2.9,0.4,4.3,1.2s2.4,1.8,3.2,3.1
C15.6,7.6,15.7,7.8,15.7,8z M14.6,8c-0.9-1.3-2-2.4-3.3-3c0.3,0.6,0.5,1.2,0.5,1.9c0,1.1-0.4,2-1.1,2.7C10,10.4,9.1,10.7,8,10.7
s-2-0.4-2.7-1.1C4.5,8.9,4.2,8,4.2,6.9c0-0.7,0.2-1.3,0.5-1.9C3.4,5.6,2.3,6.7,1.4,8c0.8,1.2,1.7,2.1,2.9,2.8c1.1,0.7,2.4,1,3.7,1
s2.6-0.3,3.7-1C12.9,10.1,13.8,9.2,14.6,8z M8.3,5c0.1-0.1,0.1-0.2,0.1-0.3c0-0.1,0-0.2-0.1-0.3C8.2,4.3,8.1,4.3,8,4.3
c-0.7,0-1.3,0.3-1.8,0.8S5.4,6.2,5.4,6.9c0,0.1,0,0.2,0.1,0.3s0.2,0.1,0.3,0.1c0.1,0,0.2,0,0.3-0.1S6.2,7,6.2,6.9
c0-0.5,0.2-0.9,0.5-1.3C7.1,5.3,7.5,5.1,8,5.1C8.1,5.1,8.2,5.1,8.3,5z"/>
</g>
</svg>
......@@ -3,15 +3,19 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#676767;}
.st0{fill:#ED1965;}
</style>
<g>
<path class="st0" d="M15.7,8c0,0.2-0.1,0.4-0.2,0.6c-0.8,1.3-1.9,2.4-3.2,3.2c-1.3,0.8-2.8,1.2-4.3,1.2s-2.9-0.4-4.3-1.2
S1.3,9.9,0.5,8.6C0.4,8.4,0.3,8.2,0.3,8c0-0.2,0.1-0.4,0.2-0.6c0.8-1.3,1.9-2.4,3.2-3.1S6.5,3.1,8,3.1s2.9,0.4,4.3,1.2
s2.4,1.8,3.2,3.1C15.6,7.6,15.7,7.8,15.7,8z M14.6,8c-0.9-1.3-2-2.4-3.3-3c0.3,0.6,0.5,1.2,0.5,1.9c0,1.1-0.4,2-1.1,2.7
C10,10.4,9.1,10.7,8,10.7s-2-0.4-2.7-1.1C4.5,8.9,4.2,8,4.2,6.9c0-0.7,0.2-1.3,0.5-1.9C3.4,5.6,2.3,6.7,1.4,8
c0.8,1.2,1.7,2.1,2.9,2.8c1.1,0.7,2.4,1,3.7,1c1.3,0,2.6-0.3,3.7-1C12.9,10.1,13.8,9.2,14.6,8z M8.3,5c0.1-0.1,0.1-0.2,0.1-0.3
c0-0.1,0-0.2-0.1-0.3C8.2,4.3,8.1,4.3,8,4.3c-0.7,0-1.3,0.3-1.8,0.8C5.7,5.6,5.4,6.2,5.4,6.9c0,0.1,0,0.2,0.1,0.3s0.2,0.1,0.3,0.1
c0.1,0,0.2,0,0.3-0.1S6.2,7,6.2,6.9c0-0.5,0.2-0.9,0.5-1.3C7.1,5.3,7.5,5.1,8,5.1C8.1,5.1,8.2,5.1,8.3,5z"/>
<path class="st0" d="M11.6,3.1C11.6,3.1,11.6,3.1,11.6,3.1C11,4.2,10,5.9,8.8,8c-1.2,2.2-2.1,3.8-2.7,4.9l-0.4,0.8
c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0-0.5-0.2-1.2-0.6c-0.1-0.1-0.1-0.1-0.1-0.2c0-0.1,0.1-0.3,0.4-0.8c-0.8-0.4-1.6-0.9-2.3-1.5
C1.6,10.1,1,9.4,0.5,8.6C0.4,8.5,0.3,8.3,0.3,8c0-0.2,0.1-0.4,0.2-0.6c0.9-1.3,2-2.4,3.3-3.2C5.1,3.5,6.5,3.1,8,3.1
c0.5,0,1,0,1.6,0.1L10,2.4c0.1-0.1,0.1-0.1,0.2-0.1c0,0,0.1,0,0.2,0.1c0.1,0,0.2,0.1,0.3,0.1s0.2,0.1,0.3,0.2
c0.1,0.1,0.2,0.1,0.3,0.2c0.1,0.1,0.2,0.1,0.2,0.1C11.5,2.9,11.6,3,11.6,3.1z M5.1,11.3l0.7-1.2C5.3,9.7,4.9,9.2,4.6,8.7
C4.3,8.1,4.2,7.5,4.2,6.9c0-0.7,0.2-1.3,0.5-1.9C3.4,5.7,2.3,6.7,1.4,8C2.4,9.5,3.6,10.6,5.1,11.3z M8.3,5c0.1-0.1,0.1-0.2,0.1-0.3
s0-0.2-0.1-0.3C8.2,4.4,8.1,4.3,8,4.3c-0.7,0-1.3,0.3-1.8,0.8C5.7,5.6,5.4,6.2,5.4,6.9c0,0.1,0,0.2,0.1,0.3
c0.1,0.1,0.2,0.1,0.3,0.1c0.1,0,0.2,0,0.3-0.1C6.2,7.1,6.2,7,6.2,6.9c0-0.5,0.2-0.9,0.5-1.3C7.1,5.3,7.5,5.1,8,5.1
C8.1,5.1,8.2,5.1,8.3,5z M15.7,8c0,0.2-0.1,0.4-0.2,0.6C15.3,9,15,9.4,14.6,9.9c-0.9,1-1.9,1.8-3,2.3S9.3,13,8,13l0.6-1.1
c1.2-0.1,2.3-0.5,3.4-1.2s1.9-1.6,2.6-2.6c-0.7-1-1.5-1.9-2.4-2.5l0.5-1c0.5,0.4,1.1,0.8,1.6,1.3c0.5,0.5,0.9,1,1.2,1.6
C15.7,7.6,15.7,7.8,15.7,8z M11.9,6.9c0,0.8-0.2,1.5-0.7,2.2s-1.1,1.1-1.8,1.4l2.4-4.3C11.9,6.5,11.9,6.7,11.9,6.9z"/>
</g>
</svg>
......@@ -7,6 +7,7 @@ import ForumTableControl from './components/forum/table-control.jsx';
import TopicsTable from './components/forum/topics-table.jsx';
import SearchHeaderContainer from './components/search/SearchHeaderContainer.jsx';
import CreateTopicModal from './components/topic/create-topic-modal.jsx';
import ForumFollowArea from './components/forum/forum-follow-area.jsx';
import navigateToFilter from '../action-creators/forum/navigate-to-filter';
import navigateToSort from '../action-creators/forum/navigate-to-sort';
......@@ -17,6 +18,7 @@ import submitNewTopic from '../action-creators/create-topic/submit-new-topic';
import navigateToTopic from '../action-creators/topic/navigate-to-topic';
import categoryUpdate from '../action-creators/create-topic/category-update';
import tagsUpdate from '../action-creators/create-topic/tags-update'
import requestUpdateForumSubscriptionState from '../action-creators/forum/request-update-forum-subscription-state';
import * as forumCatConstants from '../constants/forum-categories';
import * as forumTagConstants from '../constants/forum-tags';
......@@ -24,6 +26,7 @@ import * as forumFilterConstants from '../constants/forum-filters';
import * as forumSortConstants from '../constants/forum-sorts';
import * as navConstants from '../constants/navigation';
import * as consts from '../constants/create-topic';
import {SUBSCRIPTION_STATE_SUBSCRIBED} from '../constants/forum';
const ForumContainer = React.createClass({
displayName: 'ForumContainer',
......@@ -154,12 +157,11 @@ const ForumContainer = React.createClass({
return (
<main className="scroller">
<SearchHeaderContainer
userId={currentUser.id}
forumId={forumId}
groupName={groupName}
groupUri={groupUri}
subscriptionState={forumSubscriptionState}/>
groupUri={groupUri} />
<CategoryList
groupUri={ groupUri }
categories={ categories }/>
......@@ -175,6 +177,11 @@ const ForumContainer = React.createClass({
sortChange={this.onSortChange}
tagChange={this.onTagsChange}/>
<ForumFollowArea
groupName={groupName}
subscriptionState={forumSubscriptionState}
onSubscriptionClicked={this.onForumSubscribeClicked} />
<TopicsTable topics={topics} groupUri={groupUri}/>
<CreateTopicModal
......@@ -202,6 +209,12 @@ const ForumContainer = React.createClass({
onCategoryChange(id) { dispatch(categoryUpdate(id));},
onTopicTagsChange(tag, isAdding) { dispatch(tagsUpdate(tag, isAdding)); },
onForumSubscribeClicked(){
const {forumSubscriptionState} = this.state;
const desiredIsSubscribed = (forumSubscriptionState !== SUBSCRIPTION_STATE_SUBSCRIBED);
dispatch(requestUpdateForumSubscriptionState(desiredIsSubscribed));
},
onCreateTopicClose(){
const {categoryStore} = this.props;
dispatch(navigateToCategory(categoryStore.getActiveCategoryName()));
......
import React, { PropTypes } from 'react';
import { SUBSCRIPTION_STATE_SUBSCRIBED, SUBSCRIPTION_STATE_UNSUBSCRIBED, SUBSCRIPTION_STATE_PENDING } from '../../../constants/forum.js';
import SubscribeButton from './subscribe-button.jsx';
export default React.createClass({
displayName: 'FollowButton',
propTypes: {
className: PropTypes.string,
itemClassName: PropTypes.string,
groupName: PropTypes.string.isRequired,
subscriptionState: PropTypes.oneOf([
SUBSCRIPTION_STATE_SUBSCRIBED,
SUBSCRIPTION_STATE_UNSUBSCRIBED,
......@@ -21,18 +17,33 @@ export default React.createClass({
},
render() {
const { className, itemClassName, onClick, subscriptionState } = this.props;
const { subscriptionState, groupName } = this.props;
let buttonText, className;
if(subscriptionState === SUBSCRIPTION_STATE_SUBSCRIBED) {
buttonText = `Unwatch ${groupName} topics`;
className = "follow-button--subscribed"
}
else {
buttonText = `Watch ${groupName} topics`;
className = "follow-button--unsubscribed"
}
return (
<SubscribeButton
className={ className }
itemClassName={ itemClassName }
onClick={onClick}
subscriptionState={subscriptionState}
subscribedText="Unfollow"
unsubscribedText="Follow"
pendingText="..."/>
<button
className={className}
onClick={this.onClick}>
{buttonText}
</button>
);
},
onClick(e){
e.preventDefault();
const {onClick} = this.props;
onClick();
}
});
import React, { PropTypes } from 'react';
import Container from '../container.jsx';
import Panel from '../panel.jsx';
import FollowButton from './follow-button.jsx';
import {
SUBSCRIPTION_STATE_SUBSCRIBED,
SUBSCRIPTION_STATE_UNSUBSCRIBED,
SUBSCRIPTION_STATE_PENDING
} from '../../../constants/forum.js';
export default React.createClass({
displayName: 'ForumFollowArea',
propTypes: {
groupName: PropTypes.string.isRequired,
subscriptionState: PropTypes.oneOf([
SUBSCRIPTION_STATE_SUBSCRIBED,
SUBSCRIPTION_STATE_UNSUBSCRIBED,
SUBSCRIPTION_STATE_PENDING
]).isRequired,
onSubscriptionClicked: PropTypes.func.isRequired
},
render(){
const {subscriptionState, onSubscriptionClicked, groupName } = this.props;
return (
<Container>
<Panel className="panel--forum-follow-area">
<FollowButton
groupName={groupName}
className="forum-follow-area-button"
subscriptionState={subscriptionState}
onClick={onSubscriptionClicked}/>
</Panel>
</Container>
);
}
});
import React, { PropTypes } from 'react';
import classNames from 'classnames';
import { SUBSCRIPTION_STATE_SUBSCRIBED, SUBSCRIPTION_STATE_UNSUBSCRIBED, SUBSCRIPTION_STATE_PENDING } from '../../../constants/forum.js';
export default React.createClass({
displayName: 'SubscribeButton',
propTypes: {
subscriptionState: PropTypes.oneOf([
SUBSCRIPTION_STATE_SUBSCRIBED,
SUBSCRIPTION_STATE_UNSUBSCRIBED,
SUBSCRIPTION_STATE_PENDING
]).isRequired,
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.node),
React.PropTypes.node
]),
onClick: PropTypes.func,
className: PropTypes.string,
itemClassName: PropTypes.string,
subscribedText: PropTypes.string,
unsubscribedText: PropTypes.string,
pendingText: PropTypes.string
},
getDefaultProps() {
return {
subscribedText: 'Unsubsrcibe',
unsubscribedText: 'Subscribe',
pendingText: 'Pending'
};
},
render() {
const {children, className, itemClassName, subscriptionState} = this.props;
let {subscribedText, unsubscribedText, pendingText} = this.props;
var compiledClassNames = className + ' ' + classNames({
pending: subscriptionState === SUBSCRIPTION_STATE_PENDING
})
var subscribedCompiledClassNames = classNames({
[itemClassName]: true,
hidden: subscriptionState !== SUBSCRIPTION_STATE_SUBSCRIBED
});
var unsubscribedCompiledClassNames = classNames({
[itemClassName]: true,
hidden: subscriptionState !== SUBSCRIPTION_STATE_UNSUBSCRIBED
});
var pendingCompiledClassNames = classNames({
[itemClassName]: true,
hidden: subscriptionState !== SUBSCRIPTION_STATE_PENDING
});
var watchNodes = [
<span
key="subscribed"
className={subscribedCompiledClassNames}>
{subscribedText}
</span>,
<span
key="unsubscribed"
className={unsubscribedCompiledClassNames}>
{unsubscribedText}
</span>,
<span
key="pending"
className={pendingCompiledClassNames}>
{pendingText}
</span>
];
return (
<button
className={compiledClassNames}
onClick={this.onClick}>
{children || watchNodes}
</button>
);
},
onClick(e){
e.preventDefault();
const {onClick} = this.props;
if(onClick) { return onClick(...arguments); }
}
});
import React, { PropTypes } from 'react';
import IconButton from '../buttons/icon-button.jsx';
import {
SUBSCRIPTION_STATE_SUBSCRIBED,
......@@ -6,15 +7,13 @@ import {
SUBSCRIPTION_STATE_PENDING
} from '../../../constants/forum.js';
import SubscribeButton from './subscribe-button.jsx';
import {ICONS_WATCH_SELECTED, ICONS_WATCH} from '../../../constants/icons';
export default React.createClass({
displayName: 'WwatchButton',
displayName: 'WatchButton',
propTypes: {
className: PropTypes.string,
itemClassName: PropTypes.string,
subscriptionState: PropTypes.oneOf([
SUBSCRIPTION_STATE_SUBSCRIBED,
SUBSCRIPTION_STATE_UNSUBSCRIBED,
......@@ -25,19 +24,22 @@ export default React.createClass({
},
render() {
const { className, itemClassName, onClick, subscriptionState, children } = this.props;
const { onClick, subscriptionState, children } = this.props;
let type;
if(subscriptionState === SUBSCRIPTION_STATE_SUBSCRIBED) {
type = ICONS_WATCH_SELECTED;
}
else {
type = ICONS_WATCH;
}
return (
<SubscribeButton
className={ className }
itemClassName={ itemClassName }
<IconButton
onClick={onClick}
subscriptionState={subscriptionState}
subscribedText="Stop Watching"
unsubscribedText="Watch"
pendingText="...">
type={type}>
{children}
</SubscribeButton>
</IconButton>
);
},
......
import React, { PropTypes } from 'react';
import {dispatch} from '../../../dispatcher';
import Container from '../container.jsx';
import { SUBSCRIPTION_STATE_SUBSCRIBED, SUBSCRIPTION_STATE_UNSUBSCRIBED, SUBSCRIPTION_STATE_PENDING } from '../../../constants/forum.js';
import requestUpdateForumSubscriptionState from '../../../action-creators/forum/request-update-forum-subscription-state';
import SearchHeader from './search-header.jsx';
export default React.createClass({
......@@ -11,32 +6,17 @@ export default React.createClass({
displayName: 'SearchHeaderContainer',
propTypes: {
groupUri: PropTypes.string.isRequired,
groupName: PropTypes.string,
subscriptionState: PropTypes.oneOf([
SUBSCRIPTION_STATE_SUBSCRIBED,
SUBSCRIPTION_STATE_UNSUBSCRIBED,
SUBSCRIPTION_STATE_PENDING
]).isRequired
groupName: PropTypes.string
},
render(){
const {groupUri, groupName, subscriptionState } = this.props;
const {groupUri, groupName } = this.props;
return (
<SearchHeader
groupUri={groupUri}
groupName={groupName}
subscriptionState={subscriptionState}
onSubscribeButtonClick={this.onSubscribeButtonClick}/>
groupName={groupName} />
);
},
onSubscribeButtonClick() {
const {subscriptionState} = this.props;
const desiredIsSubscribed = (subscriptionState !== SUBSCRIPTION_STATE_SUBSCRIBED);
dispatch(requestUpdateForumSubscriptionState(desiredIsSubscribed));
}
});
......@@ -4,10 +4,8 @@ import Panel from '../panel.jsx';
import H1 from '../text/h-1.jsx';
import Input from '../forms/input.jsx';
import ForumCategoryLink from '../links/forum-category-link.jsx';
import FollowButton from '../forum/follow-button.jsx';
import CreateTopicLink from '../links/create-topic-link.jsx';
import {DEFAULT_CATEGORY_NAME} from '../../../constants/navigation';
import { SUBSCRIPTION_STATE_SUBSCRIBED, SUBSCRIPTION_STATE_UNSUBSCRIBED, SUBSCRIPTION_STATE_PENDING } from '../../../constants/forum.js';
export default React.createClass({
......@@ -16,16 +14,10 @@ export default React.createClass({
propTypes: {
groupUri: PropTypes.string.isRequired,
groupName: PropTypes.string,
subscriptionState: PropTypes.oneOf([
SUBSCRIPTION_STATE_SUBSCRIBED,
SUBSCRIPTION_STATE_UNSUBSCRIBED,
SUBSCRIPTION_STATE_PENDING
]).isRequired,
onSubscribeButtonClick: PropTypes.func.isRequired
},
render(){
const {groupUri, groupName, subscriptionState, onSubscribeButtonClick} = this.props;
const {groupUri, groupName } = this.props;
return (
<Container>
......@@ -47,11 +39,6 @@ export default React.createClass({
onChange={this.onSearchUpdate}
className="topic-search__search-input"/>
<FollowButton
subscriptionState={subscriptionState}
className="topic-search__watch-forum-button"
itemClassName="topic-search__watch-forum-button-text-item"
onClick={onSubscribeButtonClick}/>
<CreateTopicLink
groupUri={groupUri}
className="topic-search__create-topic-link">
......
import assert from 'assert';
import { spy } from 'sinon';
import React from 'react';
import { shallow } from 'enzyme';
import ForumFollowArea from '../../../../../../shared/containers/components/forum/forum-follow-area.jsx';
import {
SUBSCRIPTION_STATE_UNSUBSCRIBED,
} from '../../../../../../shared/constants/forum.js';
describe('<ForumFollowArea/>', () => {
let wrapper;
let clickHandle;
beforeEach(() => {
clickHandle = spy();
wrapper = shallow(