Skip to content

Commit d99ca34

Browse files
pom2terbenlangfeld
authored andcommitted
Make Candy responsive for mobile-friendly display
Fixes candy-chat#457 candy-chat#222
1 parent a8a18d2 commit d99ca34

File tree

9 files changed

+176
-6
lines changed

9 files changed

+176
-6
lines changed

Gruntfile.js

+17-1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,20 @@ module.exports = function(grunt) {
8282
}
8383
}
8484
},
85+
concat: {
86+
css:{
87+
src: [
88+
'bower_components/bootstrap/dist/css/bootstrap.css'
89+
],
90+
dest: 'libs.bundle.css'
91+
}
92+
},
93+
cssmin: {
94+
css:{
95+
src: 'libs.bundle.css',
96+
dest: 'libs.min.css'
97+
}
98+
},
8599
watch: {
86100
clear: {
87101
files: ['src/*.js', 'src/**/*.js', 'tests/**/*.js'],
@@ -248,6 +262,8 @@ module.exports = function(grunt) {
248262
grunt.loadNpmTasks('grunt-contrib-watch');
249263
grunt.loadNpmTasks('grunt-contrib-clean');
250264
grunt.loadNpmTasks('grunt-contrib-compress');
265+
grunt.loadNpmTasks('grunt-contrib-concat');
266+
grunt.loadNpmTasks('grunt-contrib-cssmin');
251267
grunt.loadNpmTasks('grunt-github-releaser');
252268
grunt.loadNpmTasks('grunt-prompt');
253269
grunt.loadNpmTasks('grunt-natural-docs');
@@ -261,7 +277,7 @@ module.exports = function(grunt) {
261277

262278
grunt.registerTask('test', ['intern:all']);
263279
grunt.registerTask('ci', ['todo', 'jshint', 'build', 'intern:all', 'coveralls:all', 'docs']);
264-
grunt.registerTask('build', ['uglify:libs', 'uglify:libs-min', 'uglify:bundle', 'uglify:min']);
280+
grunt.registerTask('build', ['uglify:libs', 'uglify:libs-min', 'uglify:bundle', 'uglify:min', 'concat:css', 'cssmin:css']);
265281
grunt.registerTask('default', [
266282
'jshint', 'build', 'notify:default', 'intern:unit'
267283
]);

bower.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"strophe": "1.1.3",
3636
"strophejs-plugins": "benlangfeld/strophejs-plugins#30fb089457addc37e01d69c3536dee868a90a9ad",
3737
"mustache": "0.3.0",
38-
"jquery-i18n": "1.1.1"
38+
"jquery-i18n": "1.1.1",
39+
"bootstrap": "~3.3.6"
3940
}
4041
}

example/index.html

+2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
<html lang="en">
33
<head>
44
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
56
<title>Candy - Chats are not dead yet</title>
67
<link rel="shortcut icon" href="../res/img/favicon.png" type="image/gif" />
8+
<link rel="stylesheet" type="text/css" href="../libs.min.css" />
79
<link rel="stylesheet" type="text/css" href="../res/default.css" />
810

911
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
"grunt-clear": "^0.2.1",
4444
"grunt-contrib-clean": "^0.5.0",
4545
"grunt-contrib-compress": "^0.13.0",
46+
"grunt-contrib-concat": "^0.5.1",
47+
"grunt-contrib-cssmin": "^0.14.0",
4648
"grunt-contrib-jshint": "^0.10.0",
4749
"grunt-contrib-uglify": "^0.4.0",
4850
"grunt-contrib-watch": "^0.6.1",

res/default.css

+121-3
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ ul {
6666
top: 0;
6767
right: 0;
6868
padding: 0;
69-
width: 35px;
69+
width: 30px;
7070
height: 30px;
7171
background: url(img/tab-transitions.png) repeat-y left;
7272
border-radius: 0 3px 0 0;
@@ -199,7 +199,7 @@ ul {
199199
right: 0;
200200
bottom: 0;
201201
width: 200px;
202-
margin: 30px 0 32px 0;
202+
margin: 30px 0 31px 0;
203203
background-color: #333;
204204
border-top: 1px solid black;
205205
box-shadow: inset 0 1px 0 0 #555;
@@ -363,6 +363,11 @@ ul {
363363
color: black;
364364
}
365365

366+
.message-pane .label:hover,
367+
.message-pane .label:focus {
368+
color: inherit;
369+
}
370+
366371
.message-pane .spacer {
367372
color: #aaa;
368373
font-weight: bold;
@@ -438,7 +443,7 @@ ul {
438443
bottom: 0;
439444
right: 0;
440445
margin: 3px 203px 3px 3px;
441-
padding: 5px 7px;
446+
padding: 0 10px;
442447
width: auto;
443448
font-size: 12px;
444449
line-height: 12px;
@@ -683,3 +688,116 @@ ul {
683688
color: #333;
684689
background-color: #aaa;
685690
}
691+
692+
/**
693+
* Bootstrap Responsive Design styles
694+
* It add styles to every element so we need to override some to keep the look of Candy
695+
*/
696+
*, :after, :before {
697+
-webkit-box-sizing: content-box;
698+
-moz-box-sizing: content-box;
699+
box-sizing: content-box;
700+
}
701+
702+
label {
703+
font-weight: normal;
704+
}
705+
706+
.label {
707+
font-size: 100%;
708+
font-weight: normal;
709+
text-align: left;
710+
line-height: inherit;
711+
padding: 0;
712+
color: inherit;
713+
}
714+
715+
.close {
716+
font-size: inherit;
717+
line-height: inherit;
718+
opacity: 1;
719+
text-shadow: none;
720+
}
721+
722+
#mobile-roster-icon {
723+
display: none;
724+
}
725+
726+
/*
727+
* Responsive specific styles for devices under 600px
728+
* Mainly changing the size of room, roster and message panes when opened / closed
729+
*/
730+
@media (max-width: 599px) {
731+
.room-pane .message-pane-wrapper {
732+
margin-right: 50px;
733+
}
734+
735+
.room-pane:not(.open) .roster-pane {
736+
right: -150px;
737+
}
738+
739+
.roster-pane {
740+
z-index: 10;
741+
}
742+
743+
.message-pane li>div {
744+
padding-left: 10px;
745+
}
746+
747+
.message-pane li>div.infomessage {
748+
padding-left: 30px;
749+
}
750+
751+
.message-pane .label {
752+
width: auto;
753+
margin-left: 0;
754+
}
755+
756+
.message-pane .spacer {
757+
margin: 0 5px;
758+
}
759+
760+
.room-pane:not(.open) .message-form-wrapper {
761+
margin-right: 50px;
762+
}
763+
764+
.room-pane:not(.open) .message-form {
765+
margin-right: 150px;
766+
}
767+
768+
.room-pane:not(.open) .message-form input.submit {
769+
margin-right: 53px;
770+
}
771+
772+
#mobile-roster-icon {
773+
position: fixed;
774+
top: 0;
775+
right: 0;
776+
}
777+
778+
/*
779+
* These are for the hamburger icon. The box-shadow adds the extra lines
780+
*/
781+
.box-shadow-icon {
782+
position: relative;
783+
display: block;
784+
width: 50px;
785+
height: 30px;
786+
cursor: pointer;
787+
}
788+
789+
.box-shadow-icon:before {
790+
content: "";
791+
position: absolute;
792+
left: 15px;
793+
top: 9px;
794+
width: 20px;
795+
height: 2px;
796+
background: #aaa;
797+
box-shadow: 0 5px 0 0 #aaa, 0 10px 0 0 #aaa;
798+
}
799+
800+
.box-shadow-icon:hover {
801+
background: #222;
802+
}
803+
}

src/view.js

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ Candy.View = (function(self, $) {
129129
assetsPath : this.getOptions().assets
130130
}, {
131131
tabs: Candy.View.Template.Chat.tabs,
132+
mobile: Candy.View.Template.Chat.mobileIcon,
132133
rooms: Candy.View.Template.Chat.rooms,
133134
modal: Candy.View.Template.Chat.modal,
134135
toolbar: Candy.View.Template.Chat.toolbar

src/view/pane/chat.js

+28
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ Candy.View.Pane = (function(self, $) {
199199
if (Candy.Core.getOptions().disconnectWithoutTabs) {
200200
Candy.Core.disconnect();
201201
self.Chat.Toolbar.hide();
202+
self.Chat.hideMobileIcon();
202203
return;
203204
}
204205
},
@@ -221,6 +222,32 @@ Candy.View.Pane = (function(self, $) {
221222
}
222223
},
223224

225+
/** Function: hideMobileIcon
226+
* Hide mobile roster pane icon.
227+
*/
228+
hideMobileIcon: function() {
229+
$('#mobile-roster-icon').hide();
230+
},
231+
232+
/** Function: showMobileIcon
233+
* Show mobile roster pane icon.
234+
*/
235+
showMobileIcon: function() {
236+
$('#mobile-roster-icon').show();
237+
},
238+
239+
/** Function: clickMobileIcon
240+
* Add class to 'open' roster pane (on mobile).
241+
*/
242+
clickMobileIcon: function(e) {
243+
if ($('.room-pane').is('.open')) {
244+
$('.room-pane').removeClass('open');
245+
} else {
246+
$('.room-pane').addClass('open');
247+
}
248+
e.preventDefault();
249+
},
250+
224251
/** Function: adminMessage
225252
* Display admin message
226253
*
@@ -343,6 +370,7 @@ Candy.View.Pane = (function(self, $) {
343370
if(Candy.Util.cookieExists('candy-nostatusmessages')) {
344371
$('#chat-statusmessage-control').click();
345372
}
373+
$('.box-shadow-icon').click(self.Chat.clickMobileIcon);
346374
},
347375

348376
/** Function: show

src/view/pane/room.js

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ Candy.View.Pane = (function(self, $) {
6464
// First room, show sound control
6565
if(Candy.Util.isEmptyObject(self.Chat.rooms)) {
6666
self.Chat.Toolbar.show();
67+
self.Chat.showMobileIcon();
6768
}
6869

6970
var roomId = Candy.Util.jidToId(roomJid);

src/view/template.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ Candy.View.Template = (function(self){
1919
};
2020

2121
self.Chat = {
22-
pane: '<div id="chat-pane">{{> tabs}}{{> toolbar}}{{> rooms}}</div>{{> modal}}',
22+
pane: '<div id="chat-pane">{{> tabs}}{{> mobile}}{{> toolbar}}{{> rooms}}</div>{{> modal}}',
2323
rooms: '<div id="chat-rooms" class="rooms"></div>',
2424
tabs: '<ul id="chat-tabs"></ul>',
25+
mobileIcon: '<div id="mobile-roster-icon"><a class="box-shadow-icon"></a></div>',
2526
tab: '<li class="roomtype-{{roomType}}" data-roomjid="{{roomJid}}" data-roomtype="{{roomType}}">' +
2627
'<a href="#" class="label">{{#privateUserChat}}@{{/privateUserChat}}{{name}}</a>' +
2728
'<a href="#" class="transition"></a><a href="#" class="close">\u00D7</a>' +

0 commit comments

Comments
 (0)