chat 0.0.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +20 -0
- data/README.md +47 -22
- data/Rakefile +27 -1
- data/app/assets/config/chat_manifest.js +2 -0
- data/app/assets/javascripts/chat.js +16 -0
- data/app/assets/javascripts/chat/cable.js +13 -0
- data/app/assets/javascripts/chat/channels/message.coffee +75 -0
- data/app/assets/javascripts/chat/channels/notification.coffee +44 -0
- data/app/assets/javascripts/chat/channels/status.coffee +13 -0
- data/app/assets/javascripts/chat/emojionearea.min.js +1 -0
- data/app/assets/javascripts/chat/messages.coffee +44 -0
- data/app/assets/stylesheets/chat.css +15 -0
- data/app/assets/stylesheets/chat/chat.sass +25 -0
- data/app/assets/stylesheets/chat/checkbox.sass +80 -0
- data/app/assets/stylesheets/chat/emojionearea.min.css +1 -0
- data/app/assets/stylesheets/chat/header.sass +50 -0
- data/app/assets/stylesheets/chat/launch.sass +26 -0
- data/app/assets/stylesheets/chat/list.sass +45 -0
- data/app/assets/stylesheets/chat/message_form.sass +50 -0
- data/app/assets/stylesheets/chat/new.sass +53 -0
- data/app/assets/stylesheets/chat/transcript.sass +76 -0
- data/app/channels/chat/messages_channel.rb +11 -0
- data/app/channels/chat/notification_channel.rb +10 -0
- data/app/channels/chat/status_channel.rb +12 -0
- data/app/controllers/chat/application_controller.rb +5 -0
- data/app/controllers/chat/conversations_controller.rb +30 -0
- data/app/controllers/chat/messages_controller.rb +28 -0
- data/app/helpers/chat/application_helper.rb +62 -0
- data/app/jobs/chat/application_job.rb +5 -0
- data/app/jobs/chat/message_relay_job.rb +40 -0
- data/app/jobs/chat/notification_relay_job.rb +11 -0
- data/app/jobs/chat/status_relay_job.rb +9 -0
- data/app/mailers/chat/application_mailer.rb +6 -0
- data/app/models/chat/application_record.rb +3 -0
- data/app/models/chat/conversation.rb +9 -0
- data/app/models/chat/dot_command.rb +26 -0
- data/app/models/chat/dot_command/gif.rb +17 -0
- data/app/models/chat/dot_command/leave.rb +16 -0
- data/app/models/chat/dot_command/shrug.rb +27 -0
- data/app/models/chat/dot_command/validator.rb +23 -0
- data/app/models/chat/message.rb +29 -0
- data/app/models/chat/session.rb +10 -0
- data/app/views/chat/_chat.html.haml +14 -0
- data/app/views/chat/conversations/_index.html.haml +11 -0
- data/app/views/chat/conversations/_new.html.haml +10 -0
- data/app/views/chat/conversations/_show.html.haml +9 -0
- data/app/views/chat/conversations/create.js.erb +21 -0
- data/app/views/chat/conversations/show.js.erb +12 -0
- data/app/views/chat/messages/_message.haml +13 -0
- data/app/views/layouts/chat/application.html.erb +14 -0
- data/config/routes.rb +5 -0
- data/lib/chat.rb +29 -3
- data/lib/chat/engine.rb +5 -0
- data/lib/chat/user.rb +51 -0
- data/lib/chat/version.rb +1 -1
- data/lib/generators/chat/install/install_generator.rb +68 -0
- data/lib/generators/chat/install/templates/add_chat_to_users.rb +9 -0
- data/lib/generators/chat/install/templates/chat.rb +11 -0
- data/lib/generators/chat/install/templates/create_chat.rb +29 -0
- data/lib/tasks/chat_tasks.rake +4 -0
- metadata +296 -16
- data/.gitignore +0 -9
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -21
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/chat.gemspec +0 -22
@@ -0,0 +1 @@
|
|
1
|
+
.dropdown-menu.textcomplete-dropdown[data-strategy=emojionearea]{position:absolute;z-index:1000;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;-moz-box-shadow:0 6px 12px rgba(0,0,0,.175);-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.textcomplete-dropdown[data-strategy=emojionearea] li.textcomplete-item{font-size:14px;padding:1px 3px;border:0}.dropdown-menu.textcomplete-dropdown[data-strategy=emojionearea] li.textcomplete-item a{text-decoration:none;display:block;height:100%;line-height:1.8em;padding:0 1.54em 0 .615em;color:#4f4f4f}.dropdown-menu.textcomplete-dropdown[data-strategy=emojionearea] li.textcomplete-item.active,.dropdown-menu.textcomplete-dropdown[data-strategy=emojionearea] li.textcomplete-item:hover{background-color:#e4e4e4}.dropdown-menu.textcomplete-dropdown[data-strategy=emojionearea] li.textcomplete-item.active a,.dropdown-menu.textcomplete-dropdown[data-strategy=emojionearea] li.textcomplete-item:hover a{color:#333}.dropdown-menu.textcomplete-dropdown[data-strategy=emojionearea] li.textcomplete-item .emojioneemoji{font-size:inherit;height:2ex;width:2.1ex;min-height:20px;min-width:20px;display:inline-block;margin:0 5px .2ex 0;line-height:normal;vertical-align:middle;max-width:100%;top:0}.emojionearea,.emojionearea *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.emojionearea,.emojionearea.form-control{display:block;position:relative!important;width:100%;height:auto;padding:0;font-size:14px}.emojionearea .emojionearea-editor{display:block;height:auto;max-height:80px;overflow:auto;padding:6px 57px 6px 0;line-height:1.42857143;font-size:17px;color:#212121;background-color:transparent;border:0;cursor:text;margin-right:1px;border-bottom:1px solid rgba(0,0,0,.26);word-wrap:break-word}.emojionearea .emojionearea-editor:empty:before{content:attr(placeholder);display:block;color:#bbb}.emojionearea .emojionearea-editor:focus{border:0;outline:0;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.emojionearea .emojionearea-editor .emojioneemoji,.emojionearea .emojionearea-editor [class*=emojione-]{font-size:inherit;height:2ex;width:2.1ex;min-height:20px;min-width:20px;display:inline-block;margin:-.2ex .15em .2ex;line-height:normal;vertical-align:middle;max-width:100%;top:0}.emojionearea.emojionearea-inline{height:34px}.emojionearea.emojionearea-inline>.emojionearea-editor{height:32px;min-height:20px;overflow:hidden;white-space:nowrap;position:absolute;top:0;left:12px;right:24px;padding:6px 0}.emojionearea.emojionearea-inline>.emojionearea-button{top:4px}.emojionearea .emojionearea-button{z-index:5;position:absolute;right:3px;top:3px;width:24px;height:24px;opacity:.6;cursor:pointer;-moz-transition:opacity .3s ease-in-out;-o-transition:opacity .3s ease-in-out;-webkit-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out}.emojionearea .emojionearea-button:hover{opacity:1}.emojionearea .emojionearea-button>div{display:block;width:24px;height:24px;position:absolute;-moz-transition:all .4s ease-in-out;-o-transition:all .4s ease-in-out;-webkit-transition:all .4s ease-in-out;transition:all .4s ease-in-out}.emojionearea .emojionearea-button>div.emojionearea-button-open{background-position:0 -24px;filter:alpha(enabled=false);opacity:1}.emojionearea .emojionearea-button>div.emojionearea-button-close{background-position:0 0;-webkit-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg);filter:alpha(Opacity=0);opacity:0}.emojionearea .emojionearea-button.active>div.emojionearea-button-open{-webkit-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg);filter:alpha(Opacity=0);opacity:0}.emojionearea .emojionearea-button.active>div.emojionearea-button-close{-webkit-transform:rotate(0);-o-transform:rotate(0);transform:rotate(0);filter:alpha(enabled=false);opacity:1}.emojionearea .emojionearea-picker{background:#fff;position:absolute;-moz-box-shadow:0 1px 5px rgba(0,0,0,.32);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.32);box-shadow:0 1px 5px rgba(0,0,0,.32);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;height:236px;width:316px;top:-15px;right:-15px;z-index:90;-moz-transition:all .25s ease-in-out;-o-transition:all .25s ease-in-out;-webkit-transition:all .25s ease-in-out;transition:all .25s ease-in-out;filter:alpha(Opacity=0);opacity:0;-moz-user-select:-moz-none;-ms-user-select:none;-webkit-user-select:none;user-select:none}.emojionearea .emojionearea-picker.hidden{display:none}.emojionearea .emojionearea-picker .emojionearea-wrapper{position:relative;height:236px;width:316px}.emojionearea .emojionearea-picker .emojionearea-wrapper:after{content:"";display:block;position:absolute;background-repeat:no-repeat;z-index:91}.emojionearea .emojionearea-picker .emojionearea-filters{width:100%;position:absolute;background:#F5F7F9;padding:0 0 0 7px;height:40px;z-index:95}.emojionearea .emojionearea-picker .emojionearea-filters .emojionearea-filter{display:block;float:left;height:40px;width:32px;padding:7px 1px 0;cursor:pointer;-webkit-filter:grayscale(1);filter:grayscale(1)}.emojionearea .emojionearea-picker .emojionearea-filters .emojionearea-filter.active{background:#fff}.emojionearea .emojionearea-picker .emojionearea-filters .emojionearea-filter.active,.emojionearea .emojionearea-picker .emojionearea-filters .emojionearea-filter:hover{-webkit-filter:grayscale(0);filter:grayscale(0)}.emojionearea .emojionearea-picker .emojionearea-filters .emojionearea-filter>i{width:24px;height:24px;top:0}.emojionearea .emojionearea-picker .emojionearea-filters .emojionearea-filter>img{width:24px;height:24px;margin:0 3px}.emojionearea .emojionearea-picker .emojionearea-scroll-area{height:196px;overflow:auto;overflow-x:hidden;width:100%;position:absolute;padding:0 0 5px}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-emojis-list{z-index:1}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones{position:absolute;top:6px;right:10px;height:22px;z-index:2}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone{display:inline-block;padding:0;border:0;vertical-align:middle;outline:0;background:0 0;cursor:pointer;position:relative}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone.btn-tone-0,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone.btn-tone-0:after{background-color:#ffcf3e}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone.btn-tone-1,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone.btn-tone-1:after{background-color:#fae3c5}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone.btn-tone-2,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone.btn-tone-2:after{background-color:#e2cfa5}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone.btn-tone-3,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone.btn-tone-3:after{background-color:#daa478}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone.btn-tone-4,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone.btn-tone-4:after{background-color:#a78058}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone.btn-tone-5,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones>.btn-tone.btn-tone-5:after{background-color:#5e4d43}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-bullet>.btn-tone,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-square>.btn-tone{width:20px;height:20px;margin:0;background-color:transparent}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-bullet>.btn-tone:after,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-square>.btn-tone:after{content:"";position:absolute;display:block;top:4px;left:4px;width:12px;height:12px}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-bullet>.btn-tone.active:after,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-square>.btn-tone.active:after{top:0;left:0;width:20px;height:20px}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-checkbox>.btn-tone,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-radio>.btn-tone{width:16px;height:16px;margin:0 2px}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-checkbox>.btn-tone.active:after,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-radio>.btn-tone.active:after{content:"";position:absolute;display:block;background-color:transparent;border:2px solid #fff;width:8px;height:8px;top:2px;left:2px}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-category:after,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-category:before,.emojionearea .emojionearea-picker .emojionearea-scroll-area h1:after,.emojionearea .emojionearea-picker .emojionearea-scroll-area h1:before{content:" ";clear:both;display:block}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-bullet>.btn-tone,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-bullet>.btn-tone:after,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-radio>.btn-tone,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-radio>.btn-tone:after{-moz-border-radius:100%;-webkit-border-radius:100%;border-radius:100%}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-checkbox>.btn-tone,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-checkbox>.btn-tone:after,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-square>.btn-tone,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-tones.emojionearea-tones-square>.btn-tone:after{-moz-border-radius:1px;-webkit-border-radius:1px;border-radius:1px}.emojionearea .emojionearea-picker .emojionearea-scroll-area h1{display:block;font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-size:13px;font-weight:400;color:#b2b2b2;background:#fff;line-height:20px;margin:0;padding:7px 0 5px 6px}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojionearea-category{padding:0 0 0 7px}.emojionearea .emojionearea-picker .emojionearea-scroll-area [class*=emojione-]{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;margin:0;width:24px;height:24px;top:0}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojibtn{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;width:24px;height:24px;float:left;display:block;margin:1px;padding:3px}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojibtn:hover{-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;background-color:#e4e4e4;cursor:pointer}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojibtn i,.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojibtn img{float:left;display:block;width:24px;height:24px}.emojionearea .emojionearea-picker .emojionearea-scroll-area .emojibtn img.lazy-emoji{filter:alpha(Opacity=0);opacity:0}.emojionearea .emojionearea-picker.emojionearea-filters-position-top .emojionearea-filters{top:0;-moz-border-radius-topleft:5px;-webkit-border-top-left-radius:5px;border-top-left-radius:5px;-moz-border-radius-topright:5px;-webkit-border-top-right-radius:5px;border-top-right-radius:5px}.emojionearea .emojionearea-picker.emojionearea-filters-position-top .emojionearea-scroll-area{bottom:0}.emojionearea .emojionearea-picker.emojionearea-filters-position-bottom .emojionearea-filters{bottom:0;-moz-border-radius-bottomleft:5px;-webkit-border-bottom-left-radius:5px;border-bottom-left-radius:5px;-moz-border-radius-bottomright:5px;-webkit-border-bottom-right-radius:5px;border-bottom-right-radius:5px}.emojionearea .emojionearea-picker.emojionearea-filters-position-bottom .emojionearea-scroll-area{top:0}.emojionearea .emojionearea-picker.emojionearea-picker-position-top{margin-top:-246px;right:-14px}.emojionearea .emojionearea-picker.emojionearea-picker-position-top .emojionearea-wrapper:after{width:19px;height:10px;background-position:-2px -49px;bottom:-10px;right:20px}.emojionearea .emojionearea-picker.emojionearea-picker-position-top.emojionearea-filters-position-bottom .emojionearea-wrapper:after{background-position:-2px -80px}.emojionearea .emojionearea-picker.emojionearea-picker-position-left,.emojionearea .emojionearea-picker.emojionearea-picker-position-right{margin-right:-326px;top:-8px}.emojionearea .emojionearea-picker.emojionearea-picker-position-left .emojionearea-wrapper:after,.emojionearea .emojionearea-picker.emojionearea-picker-position-right .emojionearea-wrapper:after{width:10px;height:19px;background-position:0 -60px;top:13px;left:-10px}.emojionearea .emojionearea-picker.emojionearea-picker-position-left.emojionearea-filters-position-bottom .emojionearea-wrapper:after,.emojionearea .emojionearea-picker.emojionearea-picker-position-right.emojionearea-filters-position-bottom .emojionearea-wrapper:after{background-position:right -60px}.emojionearea .emojionearea-picker.emojionearea-picker-position-bottom{margin-top:10px;right:-14px;top:47px}.emojionearea .emojionearea-picker.emojionearea-picker-position-bottom .emojionearea-wrapper:after{width:19px;height:10px;background-position:-2px -100px;top:-10px;right:20px}.emojionearea .emojionearea-picker.emojionearea-picker-position-bottom.emojionearea-filters-position-bottom .emojionearea-wrapper:after{background-position:-2px -90px}.emojionearea .emojionearea-button.active+.emojionearea-picker{filter:alpha(enabled=false);opacity:1}.emojionearea .emojionearea-button.active+.emojionearea-picker-position-top{margin-top:-229px}.emojionearea .emojionearea-button.active+.emojionearea-picker-position-left,.emojionearea .emojionearea-button.active+.emojionearea-picker-position-right{margin-right:-309px}.emojionearea .emojionearea-button.active+.emojionearea-picker-position-bottom{margin-top:-7px}.emojionearea.emojionearea-standalone{display:inline-block;width:auto;box-shadow:none}.emojionearea.emojionearea-standalone .emojionearea-editor{min-height:33px;position:relative;padding:6px 42px 6px 6px}.emojionearea.emojionearea-standalone .emojionearea-editor::before{content:"";position:absolute;top:4px;left:50%;bottom:4px;border-left:1px solid #e6e6e6}.emojionearea.emojionearea-standalone .emojionearea-editor.has-placeholder .emojioneemoji{opacity:.4}.emojionearea.emojionearea-standalone .emojionearea-button{top:0;right:0;bottom:0;left:0;width:auto;height:auto}.emojionearea.emojionearea-standalone .emojionearea-button>div{right:6px;top:5px}.emojionearea.emojionearea-standalone .emojionearea-picker.emojionearea-picker-position-bottom .emojionearea-wrapper:after,.emojionearea.emojionearea-standalone .emojionearea-picker.emojionearea-picker-position-top .emojionearea-wrapper:after{right:23px}.emojionearea.emojionearea-standalone .emojionearea-picker.emojionearea-picker-position-left .emojionearea-wrapper:after,.emojionearea.emojionearea-standalone .emojionearea-picker.emojionearea-picker-position-right .emojionearea-wrapper:after{top:15px}.emojionearea .emojionearea-button>div,.emojionearea .emojionearea-picker .emojionearea-wrapper:after{background-image:url(data:image/png;base64,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)!important}.emojionearea.emojionearea-standalone .emojionearea-editor.has-placeholder{background-repeat:no-repeat;background-position:20px 4px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMAQMAAABsu86kAAAABlBMVEUAAAC/v79T5hyIAAAAAXRSTlMAQObYZgAAABNJREFUCNdjYGNgQEb/P4AQqiAASiUEG6Vit44AAAAASUVORK5CYII=)!important}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
@import "https://fonts.googleapis.com/css?family=Lato:300&subset=latin-ext"
|
2
|
+
|
3
|
+
#chat .chat__header
|
4
|
+
font-family: 'Lato' !important
|
5
|
+
letter-spacing: 1.5px !important
|
6
|
+
height: 48px
|
7
|
+
background-color: #fff
|
8
|
+
box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.2)
|
9
|
+
display: flex
|
10
|
+
flex-direction: row
|
11
|
+
align-items: center
|
12
|
+
h6
|
13
|
+
font-family: 'Lato' !important
|
14
|
+
letter-spacing: 1.5px !important
|
15
|
+
margin: 0
|
16
|
+
font-weight: 300
|
17
|
+
font-size: 19px
|
18
|
+
i
|
19
|
+
margin: 0 10px 0 10px
|
20
|
+
color: #BDBDBD
|
21
|
+
transition: all .3s ease
|
22
|
+
cursor: pointer
|
23
|
+
&:hover
|
24
|
+
color: #212121
|
25
|
+
|
26
|
+
#chat .chat__badge
|
27
|
+
position: relative
|
28
|
+
#chat .chat__badge[data-badge]:after, .chat__launch.chat__badge[data-badge]:after
|
29
|
+
content: attr(data-badge)
|
30
|
+
display: flex
|
31
|
+
flex-direction: row
|
32
|
+
flex-wrap: wrap
|
33
|
+
justify-content: center
|
34
|
+
align-content: center
|
35
|
+
align-items: center
|
36
|
+
position: absolute
|
37
|
+
top: -7px
|
38
|
+
right: -10px
|
39
|
+
font-size: 12px
|
40
|
+
width: 22px
|
41
|
+
height: 22px
|
42
|
+
border-radius: 50%
|
43
|
+
background: #ff4081
|
44
|
+
color: #fff
|
45
|
+
font-family: 'Lato' !important
|
46
|
+
.chat__launch.chat__badge[data-badge]:after
|
47
|
+
position: fixed
|
48
|
+
bottom: 51px
|
49
|
+
right: 14px
|
50
|
+
top: initial
|
@@ -0,0 +1,26 @@
|
|
1
|
+
.chat__launch
|
2
|
+
position: fixed
|
3
|
+
right: 15px
|
4
|
+
bottom: 15px
|
5
|
+
border-radius: 50%
|
6
|
+
height: 56px
|
7
|
+
margin: auto
|
8
|
+
min-width: 56px
|
9
|
+
width: 56px
|
10
|
+
padding: 0
|
11
|
+
overflow: hidden
|
12
|
+
box-shadow: 0 1px 1.5px 0 rgba(0, 0, 0, 0.12), 0 1px 1px 0 rgba(0, 0, 0, 0.24)
|
13
|
+
line-height: normal
|
14
|
+
border: none
|
15
|
+
will-change: box-shadow
|
16
|
+
transition: box-shadow 0.2s cubic-bezier(0.4, 0, 1, 1), background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s cubic-bezier(0.4, 0, 0.2, 1)
|
17
|
+
outline: none
|
18
|
+
cursor: pointer
|
19
|
+
text-decoration: none
|
20
|
+
i
|
21
|
+
position: fixed
|
22
|
+
right: 28px
|
23
|
+
bottom: 28px
|
24
|
+
font-size: 30px
|
25
|
+
&:active
|
26
|
+
box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
@keyframes pulse
|
2
|
+
50%
|
3
|
+
background-color: #C8E6C9
|
4
|
+
|
5
|
+
#chat .chat__list
|
6
|
+
height: calc(100% - 58px)
|
7
|
+
display: flex
|
8
|
+
flex-direction: column
|
9
|
+
padding-top: 10px
|
10
|
+
a
|
11
|
+
padding: 10px
|
12
|
+
text-align: center
|
13
|
+
transition: all 0.3s ease
|
14
|
+
text-decoration: none
|
15
|
+
color: #212121
|
16
|
+
&:hover
|
17
|
+
background: #BDBDBD
|
18
|
+
.chat__index
|
19
|
+
display: flex
|
20
|
+
flex-direction: column
|
21
|
+
overflow-y: auto
|
22
|
+
&::-webkit-scrollbar
|
23
|
+
display: none
|
24
|
+
.chat__has_new_message
|
25
|
+
animation: pulse 1s ease-out infinite
|
26
|
+
|
27
|
+
#chat .chat__start-new
|
28
|
+
font-weight: 300
|
29
|
+
border-top: 1px solid #BDBDBD
|
30
|
+
margin: 0 !important
|
31
|
+
font-size: 17px
|
32
|
+
|
33
|
+
#chat .chat__none-available
|
34
|
+
height: 100%
|
35
|
+
display: flex
|
36
|
+
flex-direction: column
|
37
|
+
align-items: center
|
38
|
+
justify-content: center
|
39
|
+
color: #bdbdbd
|
40
|
+
h5
|
41
|
+
font-weight: 400
|
42
|
+
font-size: 15px
|
43
|
+
margin: 5px 0px 5px 0px
|
44
|
+
i
|
45
|
+
font-size: 60px
|
@@ -0,0 +1,50 @@
|
|
1
|
+
@import "https://fonts.googleapis.com/css?family=Lato:300&subset=latin-ext"
|
2
|
+
|
3
|
+
#chat .new_message
|
4
|
+
margin: 0px 40px 36px 40px
|
5
|
+
flex-direction: column
|
6
|
+
display: flex
|
7
|
+
position: relative
|
8
|
+
.chat__insert-image
|
9
|
+
position: absolute
|
10
|
+
right: 28px
|
11
|
+
top: 4px
|
12
|
+
color: #bdbdbd
|
13
|
+
transition: all 0.3s ease
|
14
|
+
z-index: 10
|
15
|
+
cursor: pointer
|
16
|
+
font-size: 22px
|
17
|
+
&:hover
|
18
|
+
color: #212121
|
19
|
+
input[type='text'], textarea
|
20
|
+
font-size: 17px
|
21
|
+
font-family: "Lato" !important
|
22
|
+
letter-spacing: 1.5px !important
|
23
|
+
background: transparent
|
24
|
+
border: none
|
25
|
+
font-weight: 300
|
26
|
+
border-bottom: 1px solid rgba(0,0,0,.26)
|
27
|
+
height: 28px
|
28
|
+
outline: none
|
29
|
+
resize: none
|
30
|
+
.bar, .emojionearea-bar
|
31
|
+
position: relative
|
32
|
+
&:before, &:after
|
33
|
+
content: ''
|
34
|
+
height: 2px
|
35
|
+
width: 0
|
36
|
+
bottom: 0px
|
37
|
+
position: absolute
|
38
|
+
background: #3f51b5
|
39
|
+
transition: 0.2s ease all
|
40
|
+
-moz-transition: 0.2s ease all
|
41
|
+
-webkit-transition: 0.2s ease all
|
42
|
+
&:before
|
43
|
+
left: 50%
|
44
|
+
&:after
|
45
|
+
right: 50%
|
46
|
+
input[type='text']:focus ~ .bar:before, input[type='text']:focus ~ .bar:after,
|
47
|
+
textarea:focus ~ .bar:before, textarea:focus ~ .bar:after, .emojionearea-editor:focus ~ .emojionearea-bar:before, .emojionearea-editor:focus ~ .emojionearea-bar:after
|
48
|
+
width: 50%
|
49
|
+
input[type='file']
|
50
|
+
display: none !important
|
@@ -0,0 +1,53 @@
|
|
1
|
+
@import "https://fonts.googleapis.com/css?family=Lato:300&subset=latin-ext"
|
2
|
+
|
3
|
+
#chat .new_conversation
|
4
|
+
height: calc(100% - 48px)
|
5
|
+
display: none
|
6
|
+
flex-direction: column
|
7
|
+
.chat__user-check-boxes
|
8
|
+
margin: 10px 20px 0px 20px
|
9
|
+
display: flex
|
10
|
+
flex-direction: column
|
11
|
+
height: calc(100% - 48px)
|
12
|
+
overflow-y: auto
|
13
|
+
&::-webkit-scrollbar
|
14
|
+
display: none
|
15
|
+
label
|
16
|
+
position: relative
|
17
|
+
margin: 1rem
|
18
|
+
line-height: 135%
|
19
|
+
cursor: pointer
|
20
|
+
font-size: 18px
|
21
|
+
font-family: "Lato" !important
|
22
|
+
letter-spacing: 1.5px !important
|
23
|
+
padding-left: 40px
|
24
|
+
.chat__status
|
25
|
+
&:after
|
26
|
+
content: "\2022"
|
27
|
+
&.offline
|
28
|
+
&:after
|
29
|
+
color: #EF5350
|
30
|
+
&.online
|
31
|
+
&:after
|
32
|
+
color: #AED581
|
33
|
+
|
34
|
+
input[type='submit']
|
35
|
+
border-top: 1px solid #BDBDBD
|
36
|
+
border-left: none
|
37
|
+
border-bottom: none
|
38
|
+
border-right: none
|
39
|
+
font-family: "Lato" !important
|
40
|
+
letter-spacing: 1.5px !important
|
41
|
+
font-size: 17px
|
42
|
+
background: transparent
|
43
|
+
width: 100%
|
44
|
+
padding: 10px 0 10px 0
|
45
|
+
cursor: pointer
|
46
|
+
transition: all 0.3s ease
|
47
|
+
z-index: 10
|
48
|
+
&:hover
|
49
|
+
background: #BDBDBD
|
50
|
+
|
51
|
+
#chat .chat__errors
|
52
|
+
text-align: center
|
53
|
+
color: #F44336
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#chat .current_chat
|
2
|
+
height: calc(100% - 48px)
|
3
|
+
flex-direction: column
|
4
|
+
img.chat__user-avatar
|
5
|
+
width: 50px
|
6
|
+
height: 50px
|
7
|
+
object-fit: cover
|
8
|
+
border-radius: 50%
|
9
|
+
i.chat__user-avatar
|
10
|
+
font-size: 50px
|
11
|
+
.chat__transcript
|
12
|
+
max-height: calc(100% - 78px)
|
13
|
+
overflow-y: auto
|
14
|
+
&::-webkit-scrollbar
|
15
|
+
display: none
|
16
|
+
.chat__image-message
|
17
|
+
width: 100%
|
18
|
+
padding-top: 10px
|
19
|
+
padding-bottom: 10px
|
20
|
+
img
|
21
|
+
width: 100%
|
22
|
+
border-bottom: 4px solid #C8E6C9
|
23
|
+
&.current img
|
24
|
+
border-bottom: 4px solid #B2EBF2
|
25
|
+
.chat__message
|
26
|
+
padding: 10px
|
27
|
+
display: flex
|
28
|
+
flex-direction: row
|
29
|
+
img
|
30
|
+
font-size: inherit
|
31
|
+
height: 2ex
|
32
|
+
width: 2.1ex
|
33
|
+
min-height: 20px
|
34
|
+
min-width: 20px
|
35
|
+
display: inline-block
|
36
|
+
margin: -.2ex .15em .2ex
|
37
|
+
line-height: normal
|
38
|
+
vertical-align: middle
|
39
|
+
max-width: 100%
|
40
|
+
top: 0
|
41
|
+
.text
|
42
|
+
padding: 5px
|
43
|
+
flex: 1
|
44
|
+
position: relative
|
45
|
+
&.right
|
46
|
+
margin-right: 10px
|
47
|
+
border-radius: 5px 0px 5px 5px
|
48
|
+
background: #B2EBF2
|
49
|
+
border: none
|
50
|
+
&:after
|
51
|
+
content: ""
|
52
|
+
position: absolute
|
53
|
+
border-style: solid
|
54
|
+
border-width: 0px 0 13px 15px
|
55
|
+
border-color: transparent #B2EBF2
|
56
|
+
display: block
|
57
|
+
width: 0
|
58
|
+
z-index: 1
|
59
|
+
right: -15px
|
60
|
+
top: 0px
|
61
|
+
&.left
|
62
|
+
margin-left: 10px
|
63
|
+
border-radius: 0px 5px 5px 5px
|
64
|
+
background: #C8E6C9
|
65
|
+
border: none
|
66
|
+
&:after
|
67
|
+
content: ""
|
68
|
+
position: absolute
|
69
|
+
border-style: solid
|
70
|
+
border-width: 0px 15px 13px 0px
|
71
|
+
border-color: transparent #C8E6C9
|
72
|
+
display: block
|
73
|
+
width: 0
|
74
|
+
z-index: 1
|
75
|
+
left: -15px
|
76
|
+
top: 0px
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Chat
|
2
|
+
class ConversationsController < ApplicationController
|
3
|
+
before_action Chat.logged_in_check
|
4
|
+
before_action :set_conversation, only: :show
|
5
|
+
|
6
|
+
def show
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
@conversation = Chat::Conversation.create(conversation_params)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def set_conversation
|
16
|
+
@conversation = Chat::Conversation.includes(
|
17
|
+
:users, messages: :user
|
18
|
+
).find(params[:id])
|
19
|
+
end
|
20
|
+
|
21
|
+
def conversation_params
|
22
|
+
chat_params = params.require(:conversation).permit(user_ids: [])
|
23
|
+
if chat_params[:user_ids].reject(&:blank?).present?
|
24
|
+
chat_params[:user_ids] << current_user.id
|
25
|
+
end
|
26
|
+
|
27
|
+
chat_params
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Chat
|
2
|
+
class MessagesController < ApplicationController
|
3
|
+
before_action Chat.logged_in_check
|
4
|
+
before_action :set_conversation
|
5
|
+
|
6
|
+
def create
|
7
|
+
@conversation.messages.create(message_params)
|
8
|
+
|
9
|
+
head :ok
|
10
|
+
end
|
11
|
+
|
12
|
+
def destroy
|
13
|
+
@conversation.destroy
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def set_conversation
|
19
|
+
@conversation = Chat::Conversation.find(params[:conversation_id])
|
20
|
+
end
|
21
|
+
|
22
|
+
def message_params
|
23
|
+
params.require(:message).permit(:text, :image).merge(
|
24
|
+
user_id: current_user.id
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Chat
|
2
|
+
module ApplicationHelper
|
3
|
+
def render_chat(background = nil, color = nil)
|
4
|
+
return unless send Chat.signed_in
|
5
|
+
|
6
|
+
render "chat/chat", background: background, color: color
|
7
|
+
end
|
8
|
+
|
9
|
+
def launch_chat_fab(background = "#4CAF50", color = "light")
|
10
|
+
attrs = {
|
11
|
+
class: "chat__launch", style: "background: #{background}",
|
12
|
+
data: { "current-user" => current_user.id }
|
13
|
+
}
|
14
|
+
button_tag(attrs) do
|
15
|
+
material_icon.forum.css_class("md-#{color}").to_s.html_safe
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def chatable_users
|
20
|
+
@chatable_users ||= ::User.where.not(id: current_user.id)
|
21
|
+
end
|
22
|
+
|
23
|
+
def chatable_user_check_boxes(f)
|
24
|
+
f.collection_check_boxes(:user_ids, chatable_users, :id, :name) do |b|
|
25
|
+
b.check_box + b.label(class: b.object.chat_status) do
|
26
|
+
content_tag(
|
27
|
+
:div, b.text,
|
28
|
+
class: "chat__status #{b.object.chat_status}"
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def chat_avatar(user)
|
35
|
+
if user.send(Chat.user_avatar.to_s + "?")
|
36
|
+
image_tag(user.send(Chat.user_avatar), class: "chat__user-avatar")
|
37
|
+
else
|
38
|
+
MaterialIcon.new.css_class("chat__user-avatar").person
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def chat_list
|
43
|
+
@chat_list ||=
|
44
|
+
Chat::Conversation.joins(:users)
|
45
|
+
.group("chat_sessions.conversation_id")
|
46
|
+
.select(:id, group_concat)
|
47
|
+
.merge(current_user.conversations)
|
48
|
+
.order(created_at: :desc)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def group_concat
|
54
|
+
if ActiveRecord::Base.connection.adapter_name == "SQLite"
|
55
|
+
"GROUP_CONCAT(users.#{::User.first_name} || ' ' || users.#{::User.last_name}, ', ') as names"
|
56
|
+
elsif ActiveRecord::Base.connection.adapter_name == "MySQL"
|
57
|
+
"GROUP_CONCAT(CONCAT(\"users.#{User.first_name}\",\" \", \"users.#{User.last_name}\") "\
|
58
|
+
"SEPARATOR ', ') as names"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|