Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/candy-chat/candy.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpom2ter <benoit.roy@gmail.com>2016-01-15 00:03:37 +0300
committerBen Langfeld <ben@langfeld.me>2016-02-02 00:48:44 +0300
commitd99ca34ef8a569899ba5658f5d9c62a24c5b6234 (patch)
tree73cf8b722add2cede9e6170396a170304996cb73
parenta8a18d21fb20dfebd696034f23fea7cd6520087c (diff)
Make Candy responsive for mobile-friendly display
Fixes #457 #222
-rw-r--r--Gruntfile.js18
-rw-r--r--bower.json3
-rw-r--r--example/index.html2
-rw-r--r--package.json2
-rw-r--r--res/default.css124
-rw-r--r--src/view.js1
-rw-r--r--src/view/pane/chat.js28
-rw-r--r--src/view/pane/room.js1
-rw-r--r--src/view/template.js3
9 files changed, 176 insertions, 6 deletions
diff --git a/Gruntfile.js b/Gruntfile.js
index d8a253e..1937469 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -82,6 +82,20 @@ module.exports = function(grunt) {
}
}
},
+ concat: {
+ css:{
+ src: [
+ 'bower_components/bootstrap/dist/css/bootstrap.css'
+ ],
+ dest: 'libs.bundle.css'
+ }
+ },
+ cssmin: {
+ css:{
+ src: 'libs.bundle.css',
+ dest: 'libs.min.css'
+ }
+ },
watch: {
clear: {
files: ['src/*.js', 'src/**/*.js', 'tests/**/*.js'],
@@ -248,6 +262,8 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-compress');
+ grunt.loadNpmTasks('grunt-contrib-concat');
+ grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-github-releaser');
grunt.loadNpmTasks('grunt-prompt');
grunt.loadNpmTasks('grunt-natural-docs');
@@ -261,7 +277,7 @@ module.exports = function(grunt) {
grunt.registerTask('test', ['intern:all']);
grunt.registerTask('ci', ['todo', 'jshint', 'build', 'intern:all', 'coveralls:all', 'docs']);
- grunt.registerTask('build', ['uglify:libs', 'uglify:libs-min', 'uglify:bundle', 'uglify:min']);
+ grunt.registerTask('build', ['uglify:libs', 'uglify:libs-min', 'uglify:bundle', 'uglify:min', 'concat:css', 'cssmin:css']);
grunt.registerTask('default', [
'jshint', 'build', 'notify:default', 'intern:unit'
]);
diff --git a/bower.json b/bower.json
index 4a2bace..633c873 100644
--- a/bower.json
+++ b/bower.json
@@ -35,6 +35,7 @@
"strophe": "1.1.3",
"strophejs-plugins": "benlangfeld/strophejs-plugins#30fb089457addc37e01d69c3536dee868a90a9ad",
"mustache": "0.3.0",
- "jquery-i18n": "1.1.1"
+ "jquery-i18n": "1.1.1",
+ "bootstrap": "~3.3.6"
}
}
diff --git a/example/index.html b/example/index.html
index 6087b49..d2a0551 100644
--- a/example/index.html
+++ b/example/index.html
@@ -2,8 +2,10 @@
<html lang="en">
<head>
<meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Candy - Chats are not dead yet</title>
<link rel="shortcut icon" href="../res/img/favicon.png" type="image/gif" />
+ <link rel="stylesheet" type="text/css" href="../libs.min.css" />
<link rel="stylesheet" type="text/css" href="../res/default.css" />
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
diff --git a/package.json b/package.json
index 5103e4e..feed6f1 100644
--- a/package.json
+++ b/package.json
@@ -43,6 +43,8 @@
"grunt-clear": "^0.2.1",
"grunt-contrib-clean": "^0.5.0",
"grunt-contrib-compress": "^0.13.0",
+ "grunt-contrib-concat": "^0.5.1",
+ "grunt-contrib-cssmin": "^0.14.0",
"grunt-contrib-jshint": "^0.10.0",
"grunt-contrib-uglify": "^0.4.0",
"grunt-contrib-watch": "^0.6.1",
diff --git a/res/default.css b/res/default.css
index c5d66f4..e46e290 100644
--- a/res/default.css
+++ b/res/default.css
@@ -66,7 +66,7 @@ ul {
top: 0;
right: 0;
padding: 0;
- width: 35px;
+ width: 30px;
height: 30px;
background: url(img/tab-transitions.png) repeat-y left;
border-radius: 0 3px 0 0;
@@ -199,7 +199,7 @@ ul {
right: 0;
bottom: 0;
width: 200px;
- margin: 30px 0 32px 0;
+ margin: 30px 0 31px 0;
background-color: #333;
border-top: 1px solid black;
box-shadow: inset 0 1px 0 0 #555;
@@ -363,6 +363,11 @@ ul {
color: black;
}
+.message-pane .label:hover,
+.message-pane .label:focus {
+ color: inherit;
+}
+
.message-pane .spacer {
color: #aaa;
font-weight: bold;
@@ -438,7 +443,7 @@ ul {
bottom: 0;
right: 0;
margin: 3px 203px 3px 3px;
- padding: 5px 7px;
+ padding: 0 10px;
width: auto;
font-size: 12px;
line-height: 12px;
@@ -683,3 +688,116 @@ ul {
color: #333;
background-color: #aaa;
}
+
+/**
+ * Bootstrap Responsive Design styles
+ * It add styles to every element so we need to override some to keep the look of Candy
+ */
+*, :after, :before {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+}
+
+label {
+ font-weight: normal;
+}
+
+.label {
+ font-size: 100%;
+ font-weight: normal;
+ text-align: left;
+ line-height: inherit;
+ padding: 0;
+ color: inherit;
+}
+
+.close {
+ font-size: inherit;
+ line-height: inherit;
+ opacity: 1;
+ text-shadow: none;
+}
+
+#mobile-roster-icon {
+ display: none;
+}
+
+/*
+ * Responsive specific styles for devices under 600px
+ * Mainly changing the size of room, roster and message panes when opened / closed
+ */
+@media (max-width: 599px) {
+ .room-pane .message-pane-wrapper {
+ margin-right: 50px;
+ }
+
+ .room-pane:not(.open) .roster-pane {
+ right: -150px;
+ }
+
+ .roster-pane {
+ z-index: 10;
+ }
+
+ .message-pane li>div {
+ padding-left: 10px;
+ }
+
+ .message-pane li>div.infomessage {
+ padding-left: 30px;
+ }
+
+ .message-pane .label {
+ width: auto;
+ margin-left: 0;
+ }
+
+ .message-pane .spacer {
+ margin: 0 5px;
+ }
+
+ .room-pane:not(.open) .message-form-wrapper {
+ margin-right: 50px;
+ }
+
+ .room-pane:not(.open) .message-form {
+ margin-right: 150px;
+ }
+
+ .room-pane:not(.open) .message-form input.submit {
+ margin-right: 53px;
+ }
+
+ #mobile-roster-icon {
+ position: fixed;
+ top: 0;
+ right: 0;
+ }
+
+/*
+ * These are for the hamburger icon. The box-shadow adds the extra lines
+ */
+ .box-shadow-icon {
+ position: relative;
+ display: block;
+ width: 50px;
+ height: 30px;
+ cursor: pointer;
+ }
+
+ .box-shadow-icon:before {
+ content: "";
+ position: absolute;
+ left: 15px;
+ top: 9px;
+ width: 20px;
+ height: 2px;
+ background: #aaa;
+ box-shadow: 0 5px 0 0 #aaa, 0 10px 0 0 #aaa;
+ }
+
+ .box-shadow-icon:hover {
+ background: #222;
+ }
+}
diff --git a/src/view.js b/src/view.js
index 66c21fe..4805bf0 100644
--- a/src/view.js
+++ b/src/view.js
@@ -129,6 +129,7 @@ Candy.View = (function(self, $) {
assetsPath : this.getOptions().assets
}, {
tabs: Candy.View.Template.Chat.tabs,
+ mobile: Candy.View.Template.Chat.mobileIcon,
rooms: Candy.View.Template.Chat.rooms,
modal: Candy.View.Template.Chat.modal,
toolbar: Candy.View.Template.Chat.toolbar
diff --git a/src/view/pane/chat.js b/src/view/pane/chat.js
index bfabaf7..196ba2f 100644
--- a/src/view/pane/chat.js
+++ b/src/view/pane/chat.js
@@ -199,6 +199,7 @@ Candy.View.Pane = (function(self, $) {
if (Candy.Core.getOptions().disconnectWithoutTabs) {
Candy.Core.disconnect();
self.Chat.Toolbar.hide();
+ self.Chat.hideMobileIcon();
return;
}
},
@@ -221,6 +222,32 @@ Candy.View.Pane = (function(self, $) {
}
},
+ /** Function: hideMobileIcon
+ * Hide mobile roster pane icon.
+ */
+ hideMobileIcon: function() {
+ $('#mobile-roster-icon').hide();
+ },
+
+ /** Function: showMobileIcon
+ * Show mobile roster pane icon.
+ */
+ showMobileIcon: function() {
+ $('#mobile-roster-icon').show();
+ },
+
+ /** Function: clickMobileIcon
+ * Add class to 'open' roster pane (on mobile).
+ */
+ clickMobileIcon: function(e) {
+ if ($('.room-pane').is('.open')) {
+ $('.room-pane').removeClass('open');
+ } else {
+ $('.room-pane').addClass('open');
+ }
+ e.preventDefault();
+ },
+
/** Function: adminMessage
* Display admin message
*
@@ -343,6 +370,7 @@ Candy.View.Pane = (function(self, $) {
if(Candy.Util.cookieExists('candy-nostatusmessages')) {
$('#chat-statusmessage-control').click();
}
+ $('.box-shadow-icon').click(self.Chat.clickMobileIcon);
},
/** Function: show
diff --git a/src/view/pane/room.js b/src/view/pane/room.js
index 2b42cd6..22af5d3 100644
--- a/src/view/pane/room.js
+++ b/src/view/pane/room.js
@@ -64,6 +64,7 @@ Candy.View.Pane = (function(self, $) {
// First room, show sound control
if(Candy.Util.isEmptyObject(self.Chat.rooms)) {
self.Chat.Toolbar.show();
+ self.Chat.showMobileIcon();
}
var roomId = Candy.Util.jidToId(roomJid);
diff --git a/src/view/template.js b/src/view/template.js
index 1e74011..e7c5b8d 100644
--- a/src/view/template.js
+++ b/src/view/template.js
@@ -19,9 +19,10 @@ Candy.View.Template = (function(self){
};
self.Chat = {
- pane: '<div id="chat-pane">{{> tabs}}{{> toolbar}}{{> rooms}}</div>{{> modal}}',
+ pane: '<div id="chat-pane">{{> tabs}}{{> mobile}}{{> toolbar}}{{> rooms}}</div>{{> modal}}',
rooms: '<div id="chat-rooms" class="rooms"></div>',
tabs: '<ul id="chat-tabs"></ul>',
+ mobileIcon: '<div id="mobile-roster-icon"><a class="box-shadow-icon"></a></div>',
tab: '<li class="roomtype-{{roomType}}" data-roomjid="{{roomJid}}" data-roomtype="{{roomType}}">' +
'<a href="#" class="label">{{#privateUserChat}}@{{/privateUserChat}}{{name}}</a>' +
'<a href="#" class="transition"></a><a href="#" class="close">\u00D7</a>' +