Comparar commits

...

16 Commits

Autor SHA1 Mensagem Data
sualko efb3dd025f update dependencies 2017-06-30 13:41:36 +02:00
sualko 457e175a41 support XEP-0106: JID Escaping (fix #501) 2017-06-30 13:40:59 +02:00
sualko 757770b9f7 Update README.md 2017-06-20 16:47:35 +02:00
sualko 3dee2ef385 add first tests, omit external dependencies, minor improvements 2017-06-20 16:31:40 +02:00
sualko e70b2481a8 roster change, rename contact, presence, notices 2017-06-16 15:35:30 +02:00
sualko 9023a4c9c8 allow slave tabs to send xmpp stanzas 2017-06-08 16:58:36 +02:00
sualko c5ad776f8c various improvements
- role allocator
- sync chat windows
- avatar placeholder
- and more
2017-06-02 14:13:56 +02:00
sualko 2bb914cb9a disable travis for refactoring branch 2017-06-01 13:58:50 +02:00
sualko 9158727327 remove bower and grunt
use: npm run dev
2017-06-01 13:57:59 +02:00
sualko e904bd8045 work on chat window 2017-05-10 10:48:53 +02:00
sualko 4fb2ea3ee3 start switching to typescript and handlebars 2017-05-04 10:48:32 +02:00
sualko 78cb8426c3 build v3.1.1 2017-02-14 16:19:51 +01:00
sualko daa5d35d7a check for missing files in build process 2017-02-14 16:19:38 +01:00
sualko daf6217a63 update documentation 2017-02-14 16:17:50 +01:00
sualko 479ebb3a26 update change log 2017-02-14 16:15:30 +01:00
sualko 4961e7e8e7 fix path to dependencies 2017-02-14 16:11:43 +01:00
205 arquivos alterados com 11014 adições e 14549 exclusões
+1 -1
Ver Arquivo
@@ -18,7 +18,7 @@ linters:
ImportantRule:
enabled: false
Indentation:
width: 4
width: 3
LeadingZero:
style: include_zero
NameFormat:
+4
Ver Arquivo
@@ -9,3 +9,7 @@ before_install:
script:
- ./node_modules/.bin/grunt pre-commit
branches:
except:
- refactoring
+4
Ver Arquivo
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
## 3.1.1 - 2017-02-14
### Fixed
- fix path to dependencies
## 3.1.0 - 2017-02-14
### Added
- add application states
-394
Ver Arquivo
@@ -1,394 +0,0 @@
/* global module:false */
module.exports = function(grunt) {
var dep = grunt.file.readJSON('dep.json');
var dep_files = dep.map(function(el) {
return el.file;
});
dep_files.push('<%= target %>/lib/translation.js');
// Project configuration.
grunt.initConfig({
app: grunt.file.readJSON('package.json'),
meta: {
banner: grunt.file.read('banner.js')
},
target: 'dev',
jshint: {
options: {
jshintrc: '.jshintrc'
},
gruntfile: {
src: 'Gruntfile.js'
},
files: ['src/jsxc.lib.*.js']
},
copy: {
main: {
files: [{
expand: true,
src: ['lib/emojione/assets/svg/*.svg',
'lib/otr/build/**', 'lib/otr/lib/*.js',
'lib/otr/vendor/*.js', 'lib/*.js', 'LICENSE',
'img/**', 'sound/**'
],
dest: '<%= target %>/'
}, {
expand: true,
cwd: 'lib/',
src: ['*.css'],
dest: '<%= target %>/css/'
}, {
expand: true,
cwd: 'lib/magnific-popup/dist/',
src: ['*.css'],
dest: '<%= target %>/css/'
}]
}
},
clean: ['<%= target %>/'],
usebanner: {
dist: {
options: {
position: 'top',
banner: '<%= meta.banner %>'
},
files: {
src: ['<%= target %>/*.js']
}
}
},
replace: {
version: {
src: ['<%= target %>/jsxc.js'],
overwrite: true,
replacements: [{
from: '< $ app.version $ >',
to: "<%= app.version %>"
}]
},
libraries: {
src: ['<%= target %>/jsxc.js'],
overwrite: true,
replacements: [{
from: '<$ dep.libraries $>',
to: function() {
var i, d, libraries = '';
for (i = 0; i < dep.length; i++) {
d = dep[i];
if (typeof d.name === 'string') {
libraries += '<a href="' + d.url + '">' + d.name + '</a> (' + d.license + '), ';
}
}
return libraries.replace(/, $/, '');
}
}]
},
locales: {
src: ['<%= target %>/lib/translation.js'],
overwrite: true,
replacements: [{
from: /^{/g,
to: 'var I18next = {'
}, {
from: /}$/g,
to: '};'
}]
},
template: {
src: ['tmp/template.js'],
overwrite: true,
replacements: [{
from: 'var jsxc.gui.template = {};',
to: ''
}]
},
imageUrl: {
src: ['<%= target %>/css/*.css'],
overwrite: true,
replacements: [{
from: /image-url\(["'](.+)["']\)/g,
to: 'url(\'../img/$1\')'
}]
},
// IE 10 does not like comments starting with @
todo: {
src: ['build/jsxc.js'],
overwrite: true,
replacements: [{
from: /\/\/@(.*)/g,
to: '//$1'
}]
}
},
merge_data: {
target: {
src: ['locales/*.{json,y{,a}ml}'],
dest: '<%= target %>/lib/translation.js'
}
},
concat: {
dep: {
options: {
banner: '/*!\n' +
' * <%= app.name %> v<%= app.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
' * \n' +
' * This file concatenates all dependencies of <%= app.name %>.\n' +
' * \n' +
' */\n\n',
process: function(src, filepath) {
filepath = filepath.replace(/^[a-z]+\//i, '');
if (filepath.match(/crypto\.js$/)) {
src += ';';
}
var data = dep[dep_files.indexOf(filepath)];
if (data) {
return '\n/*!\n * Source: ' + filepath + ', license: ' + data.license + ', url: ' + data.url + '\n */\n' + src;
} else {
return src;
}
}
},
src: dep_files,
dest: '<%= target %>/lib/jsxc.dep.js'
},
jsxc: {
options: {
banner: '/*! This file is concatenated for the browser. */\n\n'
},
src: ['src/jsxc.intro.js', 'src/jsxc.lib.js', 'src/jsxc.lib.xmpp.js',
'src/jsxc.lib.*.js', 'tmp/template.js', 'src/jsxc.outro.js'
],
dest: '<%= target %>/jsxc.js'
}
},
uglify: {
jsxc: {
options: {
mangle: false,
sourceMap: true,
preserveComments: 'some'
},
files: {
'<%= target %>/lib/jsxc.dep.min.js': ['<%= target %>/lib/jsxc.dep.js'],
'<%= target %>/jsxc.min.js': ['<%= target %>/jsxc.js']
}
}
},
search: {
bower: {
files: {
src: ['bower.json']
},
options: {
searchString: "<%= app.version %>",
logFormat: 'console',
onComplete: function(m) {
if (m.numMatches === 0) {
grunt.fail.fatal('No entry in bower.json for current version found.');
}
}
}
},
console: {
files: {
src: ['src/*.js']
},
options: {
searchString: /console\.log\((?!'[<>]|msg)/g,
logFormat: 'console',
failOnMatch: true
}
},
changelog: {
files: {
src: ['CHANGELOG.md']
},
options: {
searchString: "<%= app.version %>",
logFormat: 'console',
onComplete: function(m) {
if (m.numMatches === 0) {
grunt.fail.fatal("No entry in CHANGELOG.md for current version found.");
}
}
}
}
},
compress: {
main: {
options: {
archive: "archives/jsxc-<%= app.version %>.zip"
},
files: [{
src: ['**'],
expand: true,
dest: 'jsxc/',
cwd: 'build/'
}]
}
},
dataUri: {
dist: {
src: '<%= target %>/css/*.css',
dest: '<%= target %>/css/',
options: {
target: ['<%= target %>/img/*.*', '<%= target %>/img/**/*.*'],
fixDirLevel: false,
maxBytes: 2048
}
}
},
jsdoc: {
dist: {
src: ['src/jsxc.lib.*'],
dest: 'doc'
}
},
autoprefixer: {
no_dest: {
src: '<%= target %>/css/*.css'
}
},
csslint: {
strict: {
options: {
import: 2
},
src: ['<%= target %>/css/*.css']
},
},
sass: {
dist: {
files: {
'<%= target %>/css/jsxc.css': 'scss/jsxc.scss',
'<%= target %>/css/jsxc.webrtc.css': 'scss/jsxc.webrtc.scss'
}
}
},
watch: {
locales: {
files: ['locales/*'],
tasks: ['merge_data', 'replace:locales', 'concat:dep']
},
css: {
files: ['scss/*'],
tasks: ['sass', 'autoprefixer', 'replace:imageUrl']
},
js: {
files: ['src/jsxc.lib.*'],
tasks: ['concat:jsxc']
},
template: {
files: ['template/*.html'],
tasks: ['htmlConvert', 'replace:template', 'concat:jsxc']
}
},
jsbeautifier: {
'default': {
src: ['Gruntfile.js', 'src/jsxc.lib.*', 'template/*.html',
'example/*.html', 'example/js/dev.js', 'example/js/example.js',
'example/css/example.css'
],
options: {
config: '.jsbeautifyrc'
}
},
'pre-commit': {
src: ['Gruntfile.js', 'src/jsxc.lib.*', 'template/*.html',
'example/*.html', 'example/js/dev.js', 'example/js/example.js',
'example/css/example.css'
],
options: {
config: '.jsbeautifyrc',
mode: 'VERIFY_ONLY'
}
}
},
prettysass: {
options: {
alphabetize: false,
indent: 4
},
jsxc: {
src: ['scss/*.scss']
}
},
htmlConvert: {
options: {
target: 'js',
rename: function(name) {
return name.match(/([-_0-9a-z]+)\.html$/i)[1];
},
quoteChar: '\'',
indentString: '',
indentGlobal: ''
},
'jsxc.gui.template': {
src: 'template/*.html',
dest: 'tmp/template.js'
}
},
scsslint: {
files: ['scss/*.scss'],
options: {
config: '.scss-lint.yml'
}
}
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-banner');
grunt.loadNpmTasks('grunt-text-replace');
grunt.loadNpmTasks('grunt-search');
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.loadNpmTasks('grunt-jsdoc');
grunt.loadNpmTasks('grunt-data-uri');
grunt.loadNpmTasks('grunt-merge-data');
grunt.loadNpmTasks('grunt-contrib-csslint');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-jsbeautifier');
grunt.loadNpmTasks('grunt-prettysass');
grunt.loadNpmTasks('grunt-html-convert');
grunt.loadNpmTasks('grunt-scss-lint');
//Default task
grunt.registerTask('default', ['build', 'watch']);
grunt.registerTask('build', ['jshint', 'clean', 'sass', 'replace:imageUrl',
'autoprefixer', 'copy', 'merge_data', 'replace:locales', 'htmlConvert',
'replace:template', 'concat'
]);
grunt.registerTask('build:prerelease', 'Build a new pre-release', function() {
grunt.config.set('target', 'build');
grunt.task.run(['search:console', 'search:bower', 'build', 'usebanner',
'replace:version', 'replace:libraries', 'replace:todo',
'uglify', 'compress'
]);
});
grunt.registerTask('build:release', 'Build a new release', function() {
grunt.config.set('target', 'build');
grunt.task.run(['search:changelog', 'build:prerelease', 'jsdoc']);
});
// before commit
grunt.registerTask('pre-commit', ['search:console', 'jsbeautifier:pre-commit', 'scsslint', 'jshint']);
grunt.registerTask('beautify', ['jsbeautifier', 'prettysass']);
};
+6 -1
Ver Arquivo
@@ -1,4 +1,4 @@
# JavaScript XMPP Client
# JavaScript XMPP Client 4.0
[![Build Status](https://travis-ci.org/jsxc/jsxc.svg?branch=master)](https://travis-ci.org/jsxc/jsxc)
[![Dependency Status](https://dependencyci.com/github/jsxc/jsxc/badge)](https://dependencyci.com/github/jsxc/jsxc)
@@ -8,3 +8,8 @@ Real-time chat app. This app requires an external XMPP server (openfire, ejabber
You find a full list of features, supported protocols and browsers on [our homepage](http://www.jsxc.org).
If you are looking for install instructions or developer notes, please also checkout our [wiki](https://github.com/jsxc/jsxc/wiki/).
## Rewrite / Refactoring
:warning: This branch is under heavy construction and definitely not ready for production.
This next big step for JSXC uses [Typescript](http://www.typescriptlang.org/index.html), [Webpack](https://webpack.github.io), [Handlebars](http://handlebarsjs.com), [Karma](http://karma-runner.github.io), [Mocha](https://mochajs.org), [Chai](http://chaijs.com) and [Sinon](http://sinonjs.org) to bring the best open XMPP chat experience to you. Currently we ship no packed version, so install all dependencies with `npm install` and execute `npm run dev` to test the current state. An example application is available at `example/ts.html`. To run all tests, enter `npm test`.
-39
Ver Arquivo
@@ -1,39 +0,0 @@
{
"name": "jsxc",
"version": "3.1.0",
"homepage": "https://www.jsxc.org",
"authors": [
"sualko <klaus@jsxc.org>"
],
"description": "Real-time chat app",
"keywords": [
"javascript",
"xmpp",
"webrtc",
"otr",
"chat",
"realtime"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"lib/",
"test",
"tests"
],
"private": true,
"devDependencies": {
"emojione": "~2.2.7",
"favico.js": "^0.3.10",
"strophe.bookmarks": "strophe/strophejs-plugin-bookmarks#f51c60629cb0ad278f92bfb8d8dbb8cb455d9c98",
"strophe.js": "strophejs#a11ebefa3db1b6712d51d0d309b9f68f8e391d1b",
"strophe.vcard": "strophe/strophejs-plugin-vcard#de3a0c97a2c520ed900ee15b04a0c16d5c663891",
"strophe.x": "strophe/strophejs-plugin-dataforms",
"strophe.chatstates": "strophe/strophejs-plugin-chatstates",
"jquery-i18next": "^1.2.0",
"i18next": "^5.0.0",
"magnific-popup": "^1.1.0"
}
}
+3 -3
Ver Arquivo
@@ -1,5 +1,5 @@
/*!
* jsxc v3.1.0 - 2017-02-14
* jsxc v3.1.1 - 2017-02-14
*
* Copyright (c) 2017 Klaus Herberth <klaus@jsxc.org> <br>
* Released under the MIT license
@@ -7,7 +7,7 @@
* Please see http://www.jsxc.org/
*
* @author Klaus Herberth <klaus@jsxc.org>
* @version 3.1.0
* @version 3.1.1
* @license MIT
*/
@@ -25,7 +25,7 @@ var jsxc = null, RTC = null, RTCPeerconnection = null;
*/
jsxc = {
/** Version of jsxc */
version: '3.1.0',
version: '3.1.1',
/** True if i'm the master */
master: false,
+3 -3
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+1122 -1
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+1 -1
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+7
Ver Arquivo
@@ -0,0 +1,7 @@
declare module '*.hbs' {
// const content: any;
// export default content;
export default function template(options:any);
}
declare function require(file:string):(context?:any, options?:any)=>string;
-116
Ver Arquivo
@@ -1,116 +0,0 @@
[
{
"name": "strophe.js",
"file": "lib/strophe.js/strophe.js",
"license": "multiple",
"url": "http://strophe.im/strophejs/"
},
{
"name": "strophe.js/muc",
"file": "lib/strophe.muc.js",
"license": "MIT",
"url": "https://github.com/strophe/strophejs-plugins"
},
{
"name": "strophe.js/disco",
"file": "lib/strophe.disco.js",
"license": "MIT",
"url": "https://github.com/strophe/strophejs-plugins"
},
{
"name": "strophe.js/caps",
"file": "lib/strophe.caps.js",
"license": "MIT",
"url": "https://github.com/strophe/strophejs-plugins"
},
{
"name": "strophe.js/vcard",
"file": "lib/strophe.vcard/index.js",
"license": "MIT",
"url": "https://github.com/strophe/strophejs-plugins"
},
{
"name": "strophe.js/bookmarks",
"file": "lib/strophe.bookmarks/index.js",
"license": "MIT",
"url": "https://github.com/strophe/strophejs-plugins/tree/master/bookmarks"
},
{
"name": "strophe.js/x",
"file": "lib/strophe.x/index.js",
"license": "MIT",
"url": "https://github.com/strophe/strophejs-plugins/tree/master/dataforms"
},
{
"name": "strophe.js/chatstates",
"file": "lib/strophe.chatstates/index.js",
"license": "MIT",
"url": "https://github.com/strophe/strophejs-plugins/tree/master/chatstates"
},
{
"name": "strophe.jinglejs",
"file": "lib/strophe.jinglejs/strophe.jinglejs-bundle.js",
"license": "MIT",
"url": "https://github.com/sualko/strophe.jinglejs"
},
{
"name": "Salsa20",
"file": "lib/otr/build/dep/salsa20.js",
"license": "AGPL3",
"url": "https://github.com/neoatlantis/node-salsa20"
},
{
"name": "bigint",
"file": "lib/otr/build/dep/bigint.js",
"license": "public domain",
"url": "www.leemon.com"
},
{
"name": "cryptojs",
"file": "lib/otr/build/dep/crypto.js",
"license": "code.google.com/p/crypto-js/wiki/license",
"url": "code.google.com/p/crypto-js"
},
{
"name": "eventemitter",
"file": "lib/otr/build/dep/eventemitter.js",
"license": "MIT",
"url": "http://git.io/ee"
},
{
"name": "otr.js",
"file": "lib/otr/build/otr.js",
"license": "MPL v2.0",
"url": "https://arlolra.github.io/otr/"
},
{
"name": "i18next",
"file": "lib/i18next/i18next.min.js",
"license": "MIT",
"url": "http://i18next.com/"
},
{
"name": "jquery-i18next",
"file": "lib/jquery-i18next/jquery-i18next.min.js",
"license": "MIT",
"url": "http://i18next.com/"
},
{
"name": "Magnific Popup",
"file": "lib/magnific-popup/dist/jquery.magnific-popup.min.js",
"license": "MIT",
"url": "http://dimsemenov.com/plugins/magnific-popup/"
},
{
"name": "favico.js",
"file": "lib/favico.js/favico.js",
"license": "MIT",
"url": "https://github.com/ejci/favico.js"
},
{
"name": "emoji one",
"file": "lib/emojione/lib/js/emojione.js",
"license": "CC-BY 4.0",
"url": "http://emojione.com"
}
]
+1 -1
Ver Arquivo
@@ -458,7 +458,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -56,7 +56,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -3620,7 +3620,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -1020,7 +1020,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -658,7 +658,7 @@ otherwise only dialog with given name is closed.
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -4148,7 +4148,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -536,7 +536,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -1707,7 +1707,7 @@ alphabetical of the name
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -3441,7 +3441,7 @@ and save. Check border cases and remove html.
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -5073,7 +5073,7 @@ normal signal
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -309,7 +309,7 @@ jsxc.Message.PLAIN = 'plain';
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -291,7 +291,7 @@ $(document).on('update.gui.jsxc', function(ev, bid) {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -3169,7 +3169,7 @@ jsxc.gui.template.get = function(name, bid, msg) {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -1007,7 +1007,7 @@ jsxc = {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -1720,7 +1720,7 @@ $(document).one('connected.jsxc', function() {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -195,7 +195,7 @@ jsxc.notice = {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -319,7 +319,7 @@ jsxc.notification = {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -349,7 +349,7 @@ jsxc.options = {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -574,7 +574,7 @@ jsxc.otr = {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -660,7 +660,7 @@ jsxc.storage = {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -102,7 +102,7 @@ jsxc.tab = {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -1524,7 +1524,7 @@ $(document).ready(function() {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -387,7 +387,7 @@ jsxc.xmpp.bookmarks.showDialog = function(room) {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -290,7 +290,7 @@ $(document).on('attached.jsxc', jsxc.xmpp.chatState.init);
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -372,7 +372,7 @@ $(document).on('stateChange.jsxc', function(ev, state) {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -1396,7 +1396,7 @@ jsxc.xmpp.carbons = {
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -2446,7 +2446,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -1405,7 +1405,7 @@ messages.
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -2760,7 +2760,7 @@ modification is done to it.
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -2220,7 +2220,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -2332,7 +2332,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -434,7 +434,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -3444,7 +3444,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -1022,7 +1022,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -504,7 +504,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -1185,7 +1185,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -1620,7 +1620,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+1 -1
Ver Arquivo
@@ -1316,7 +1316,7 @@
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 13:39:34 GMT+0100 (CET)
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Tue Feb 14 2017 16:15:49 GMT+0100 (CET)
</footer>
<script> prettyPrint(); </script>
+92
Ver Arquivo
@@ -0,0 +1,92 @@
<!DOCTYPE HTML>
<html>
<head>
<title>JSXC example application</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
<link href="css/bootstrap.min.css" media="all" rel="stylesheet" type="text/css" />
<!-- require:dependencies -->
<link href="../build/css/jquery-ui.min.css" media="all" rel="stylesheet" type="text/css" />
<link href="../css/bundle.css" media="all" rel="stylesheet" type="text/css" />
<!-- endrequire -->
<link href="../node_modules/simplebar/dist/simplebar.css" media="all" rel="stylesheet" type="text/css" />
<link href="css/example.css" media="all" rel="stylesheet" type="text/css" />
<style>
#jsxc-role {
width: 50px;
height: 50px;
background-color: #a1a1a1;
border-radius: 50%;
position: absolute;
top: 15px;
left: 15px;
}
.jsxc-master #jsxc-role {
background-color: green;
}
.jsxc-slave #jsxc-role {
background-color: orange;
}
</style>
</head>
<body>
<div id="jsxc-role"></div>
<form id="loginForm" style="margin-top: 100px; padding:15px;" class="form-inline">
<div class="form-group">
<input class="form-control" type="text" name="url" placeholder="Bosh url" value="/http-bind/" />
</div>
<div class="form-group">
<input class="form-control" type="text" name="jid" placeholder="Jabber Id" value="" />
</div>
<div class="form-group">
<input class="form-control" type="text" name="password" placeholder="Password" value="" />
</div>
<button class="btn btn-primary">Login</button>
</form>
<p style="padding:15px"><a class="btn btn-danger" href="javascript:jsxc.deleteAllData()">Delete all Data</a>
<a class="btn btn-default" href="javascript:jsxc.enableDebugMode()">Enable Debug Mode</a>
<a class="btn btn-default" href="javascript:jsxc.disableDebugMode()">Disable Debug Mode</a></p>
<!-- require:dependencies -->
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script src="../build/lib/jquery.slimscroll.js"></script>
<script src="../build/lib/jquery.fullscreen.js"></script>
<!-- <script src="../build/lib/jsxc.dep.js"></script> -->
<!-- endrequire -->
<script src="../node_modules/simplebar/dist/simplebar.js"></script>
<script src="js/bootstrap.min.js"></script>
<!-- jsxc library -->
<script src="../bundle.js"></script>
<script>
$('#loginForm').submit(function(ev){
ev.preventDefault();
var url = $(this).find('[name="url"]').val();
var jid = $(this).find('[name="jid"]').val();
var password = $(this).find('[name="password"]').val();
jsxc.start(url, jid, password);
});
</script>
</body>
</html>
+51
Ver Arquivo
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg8"
version="1.1"
viewBox="0 0 3.1749999 3.1750001"
height="12"
width="12"
inkscape:version="0.91 r13725"
sodipodi:docname="presence_online.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1879"
inkscape:window-height="1176"
id="namedview5307"
showgrid="false"
inkscape:zoom="55.625733"
inkscape:cx="3.7142348"
inkscape:cy="6.3732363"
inkscape:window-x="1241"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="svg8" />
<defs
id="defs2" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
</svg>

Depois

Largura:  |  Altura:  |  Tamanho: 1.4 KiB

+100
Ver Arquivo
@@ -0,0 +1,100 @@
// jshint node:true
// var path = require('path');
var webpackConfig = require('./webpack.config.js');
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: [ /*'karma-typescript',*/ 'mocha', 'chai'],
// list of files / patterns to load in the browser
files: [
'./node_modules/jquery/dist/jquery.min.js',
'./node_modules/strophe.js/strophe.js',
'./node_modules/es6-promise/dist/es6-promise.js',
'test/*.spec.ts',
'test/**/*.spec.ts'
],
// list of files to exclude
exclude: [],
// webpack configuration
webpack: {
devtool: 'eval-source-map',
module: webpackConfig.module,
resolve: webpackConfig.resolve,
//externals: webpackConfig.externals,
// target: 'node',
node: {
fs: 'empty'
}
},
webpackMiddleware: {
quiet: false,
stats: {
colors: true
}
},
mime: {
'text/x-typescript': ['ts', 'tsx']
},
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'test/**/*.spec.ts': ['webpack' /*'karma-typescript'*/ ]
},
karmaTypescriptConfig: {
include: ['test/**/*.spec.ts']
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: [ /*'progress', 'karma-typescript',*/ 'mocha'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_DEBUG,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
});
};
+52 -23
Ver Arquivo
@@ -1,6 +1,6 @@
{
"name": "jsxc",
"version": "3.1.0",
"version": "3.1.1",
"description": "Real-time xmpp chat application with video calls, file transfer and encrypted communication",
"homepage": "http://www.jsxc.org/",
"bugs": "https://github.com/jsxc/jsxc/issues",
@@ -10,30 +10,59 @@
"type": "git",
"url": "https://github.com/jsxc/jsxc"
},
"scripts": {
"start": "webpack --config webpack.config.js",
"dev": "webpack --config webpack.config.js --watch",
"test": "karma start"
},
"devDependencies": {
"@types/chai": "^4.0.0",
"@types/jquery": "^3.2.3",
"@types/mocha": "^2.2.41",
"@types/simplebar": "^2.4.0",
"@types/sinon": "^2.3.1",
"autoprefixer-core": "^6.0.1",
"bower": "^1.8.0",
"grunt": "^1.0.1",
"grunt-autoprefixer": "^3.0.4",
"grunt-banner": "~0.6.0",
"grunt-contrib-clean": "~1.0.0",
"grunt-contrib-compress": "^1.4.1",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-copy": "~1.0.0",
"grunt-contrib-csslint": "^2.0.0",
"grunt-contrib-jshint": "~1.1.0",
"grunt-contrib-uglify": "^2.0.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-data-uri": "^0.3.0",
"grunt-html-convert": "0.0.2",
"grunt-jsbeautifier": "^0.2.13",
"grunt-jsdoc": "^2.1.0",
"grunt-merge-data": "^0.4.5",
"grunt-prettysass": "^0.2.3",
"grunt-sass": "2.0.0",
"grunt-scss-lint": "^0.5.0",
"grunt-search": "^0.1.8",
"grunt-text-replace": "~0.4.0",
"node-sass": "4.3.0"
"chai": "^4.0.2",
"css-loader": "^0.28.4",
"es6-promise": "^4.1.0",
"extract-text-webpack-plugin": "^2.1.2",
"handlebars-loader": "^1.5.0",
"handlebars-runtime": "^1.0.12",
"i18next": "^8.4.2",
"karma": "^1.7.0",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^2.1.1",
"karma-firefox-launcher": "^1.0.1",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.3",
"karma-phantomjs-launcher": "^1.0.4",
"karma-sinon": "^1.0.5",
"karma-spec-reporter": "0.0.31",
"karma-typescript": "^3.0.4",
"karma-webpack": "^2.0.3",
"mocha": "^3.4.2",
"node-sass": "^4.5.3",
"precompile-handlebars": "^1.0.5",
"resolve-url-loader": "^2.0.3",
"sass-loader": "^6.0.6",
"sinon": "^2.3.5",
"strophe": "^1.2.4",
"ts-loader": "^2.2.0",
"ts-node": "^3.1.0",
"typescript": "^2.3.4",
"webpack": "^3.0.0"
},
"dependencies": {
"@types/emojione": "^2.2.1",
"@types/handlebars": "^4.0.33",
"@types/strophe": "^1.2.28",
"i18next": "^7.1.1",
"jquery": "^3.2.1",
"magnific-popup": "^1.1.0",
"moment": "^2.18.1",
"simplebar": "^2.4.3",
"strophe.js": "^1.2.14",
"tslib": "^1.7.1"
}
}
-72
Ver Arquivo
@@ -1,72 +0,0 @@
@import "modules";
#jsxc_buddylist {
list-style: none;
padding: 0;
margin: 0;
width: 204px;
z-index: 85;
.jsxc_unreadMsg {
.jsxc_name {
padding-right: 0;
}
}
.jsxc_oneway {
.jsxc_avatar, .jsxc_caption {
opacity: 0.7;
}
}
.jsxc_right {
float: right;
margin-right: 6px;
div {
font-weight: bold;
text-align: center;
font-size: 13px;
line-height: 20px;
color: $white;
&:hover {
opacity: 1;
}
}
}
.jsxc_more {
margin-right: 6px;
z-index: 10;
position: relative;
}
.jsxc_options {
height: 20px;
float: left;
border-radius: 2px;
background-color: $roster_icon_bg;
> div {
height: 20px;
width: 20px;
float: left;
margin-right: 0 1px;
background-repeat: no-repeat;
background-position: center center;
opacity: 0.6;
cursor: pointer;
&:hover {
opacity: 1;
}
}
}
&.jsxc_hideOffline {
.jsxc_rosteritem[data-status='offline'] {
display: none;
}
}
}
-57
Ver Arquivo
@@ -1,57 +0,0 @@
@import "../lib/magnific-popup/src/css/main";
@import "../lib/emojione/assets/css/emojione";
// BEGIN: bootstrap
@import "../lib/bootstrap/assets/stylesheets/bootstrap/variables";
@import "../lib/bootstrap/assets/stylesheets/bootstrap/mixins";
// Spec and IE10+
@keyframes progress-bar-stripes {
from {
background-position: 40px 0;
}
to {
background-position: 0 0;
}
}
#jsxc_dialog {
@import "../lib/bootstrap/assets/stylesheets/bootstrap/progress-bars";
}
#jsxc_dialog, #jsxc_webrtc {
@import "../lib/bootstrap/assets/stylesheets/bootstrap/utilities";
@import "../lib/bootstrap/assets/stylesheets/bootstrap/code";
@import "../lib/bootstrap/assets/stylesheets/bootstrap/grid";
@import "../lib/bootstrap/assets/stylesheets/bootstrap/alerts";
@import "../lib/bootstrap/assets/stylesheets/bootstrap/buttons";
@import "../lib/bootstrap/assets/stylesheets/bootstrap/button-groups";
@import "../lib/bootstrap/assets/stylesheets/bootstrap/forms";
.progress {
margin-bottom: 0;
.progress-bar {
width: 100%;
}
}
.mfp-close {
font-size: 23px;
}
}
.mfp-bg {
z-index: 9000;
}
.mfp-wrap {
z-index: 9010;
}
.mfp-content {
text-align: center;
}
// END: bootstrap
-530
Ver Arquivo
@@ -1,530 +0,0 @@
.jsxc_right {
text-align: right;
}
.jsxc_center {
text-align: center;
}
.jsxc_hidden {
display: none;
}
.jsxc_clear {
clear: both;
}
.jsxc_uppercase {
text-transform: uppercase;
}
.jsxc_sep {
border-top: 1px solid $separator;
}
.jsxc_name {
overflow: hidden;
cursor: pointer;
text-overflow: ellipsis;
white-space: nowrap;
}
.jsxc_maxWidth {
max-width: 500px;
}
.jsxc_meta {
text-align: right;
font-style: italic;
}
#jsxc_dialog {
padding: 20px;
min-width: 320px;
max-width: 100%;
display: inline-block;
text-align: left;
position: relative;
background: #FFF;
width: auto;
* {
box-sizing: border-box;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
margin: 0;
padding: 0;
}
p {
margin-bottom: 1em;
input {
margin-bottom: 5px;
width: 60%;
outline: none;
}
input[type='submit'] {
width: auto;
}
}
table {
margin-bottom: 1em;
}
hr {
border: 0;
border-top: 1px solid #eee;
margin-top: 20px;
margin-bottom: 20px;
}
h3 {
font-size: 120%;
font-weight: bold;
margin-bottom: 10px;
margin-top: 20px;
}
.jsxc_right {
margin-top: 20px;
}
form {
fieldset {
margin-bottom: 30px;
padding: 0 30px;
border: 1px solid #d9d9d9;
h3 {
font-size: 15px;
color: #000;
background-color: #f2f2f2;
padding: 10px;
margin: 0 -30px 10px;
}
}
}
legend {
border: 0;
font-size: 20px;
}
input {
outline: none;
&:invalid {
border: 1px solid $dialog_input_invalid;
}
}
.btn-group button {
margin-right: 0;
}
input[readonly] {
background-color: $dialog_input_readonly_bg;
}
.jsxc_inputinfo {
padding: 0;
font-style: italic;
margin: 0;
}
.jsxc_waiting {
&:before {
content: " ";
width: 1em;
height: 1em;
display: inline-block;
background-size: 100%;
margin: 0 3px 0 0;
background-image: image-url("loading.gif");
}
}
.jsxc_libraries, .jsxc_credits {
max-width: 300px;
}
.jsxc_warning {
display: block;
background-color: #fbfe7a;
padding: 3px 10px;
border-radius: 3px;
}
}
.jsxc_avatar {
width: 36px;
height: 36px;
line-height: 36px;
margin: 0 5px;
background-color: $avatar_bg;
border-radius: 50%;
float: left;
text-align: center;
font-weight: bold;
font-size: 30px;
color: $avatar_color;
position: relative;
font-family: $font_sans;
background-size: cover;
background-position: center center;
img {
display: block;
width: 25px;
height: 25px;
position: absolute;
top: 0;
left: 0;
}
&:before {
position: absolute;
top: -2px;
left: -6px;
border: 2px solid $roster_bg;
}
}
ul.jsxc_vCard {
min-width: 400px;
ul {
margin-left: 20px;
}
li {
cursor: default !important;
}
}
// Spot which is attached to xmpp: uris
.jsxc_spot {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
text-indent: -99999em;
margin-top: 3px;
margin-right: 5px;
line-height: 100%;
cursor: pointer;
border: 1px solid $spot_border;
background-color: $white;
&:before {
position: absolute;
}
&.jsxc_online, &.jsxc_chat, &.jsxc_away, &.jsxc_xa, &.jsxc_dnd, &.jsxc_offline {
border: 0;
}
}
.jsxc_unread {
display: none;
}
.jsxc_unreadMsg {
.jsxc_name {
font-style: italic;
}
.jsxc_unread {
display: block;
background-color: $unread_bg;
border-radius: 11px;
color: $unread_color;
font-size: 80%;
padding: 2px;
line-height: 15px;
float: right;
margin-right: 3px;
margin-top: 4px;
}
}
// TODO: check if required
.jsxc_list {
.jsxc_inner {
box-sizing: border-box;
max-height: 0;
transition: max-height 0.5s;
overflow: hidden;
visibility: hidden;
position: absolute;
bottom: 100%;
left: 0;
}
&.jsxc_opened {
.jsxc_inner {
max-height: 1000px;
visibility: visible;
display: block;
}
}
}
#cboxWrapper {
outline: none;
}
.jsxc_loading {
margin: 0 auto;
width: 32px;
height: 32px;
border: 0;
background-size: 32px 32px !important;
background: image-url("loading.gif");
}
// @TODO: check
#jsxc_loginForm input[type='submit'] {
height: 34px;
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: normal;
line-height: 1.428571429;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
border: 1px solid transparent;
border-radius: 4px;
user-select: none;
color: $white;
background-color: $loginForm_bg;
border-color: $loginForm_border;
}
.jsxc_oneway .jsxc_avatar {
filter: grayscale(100%);
}
img.jsxc_vCard {
float: right;
max-width: 200px;
max-height: 200px;
border: 5px solid $white;
border-radius: 2px;
}
.jsxc_alert {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
&.jsxc_alert-warning {
color: #8a6d3b;
background-color: #fcf8e3;
border-color: #faebcc;
}
}
.jsxc_btn {
width: auto;
min-width: 25px;
display: inline-block;
padding: 6px 12px;
margin: 0 2px;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
transition: background-color 0.5s;
&.jsxc_btn-default {
border-color: #ccc;
color: #555;
background-color: rgba(240, 240, 240, 0.9);
&:hover {
background-color: #d6d6d6;
}
}
&.jsxc_btn-primary {
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
&:hover {
background-color: #296496;
}
}
&[disabled], &[disabled]:hover {
opacity: 0.65;
cursor: not-allowed;
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
}
}
.jsxc_menu {
display: none;
position: absolute;
background-color: #FFF;
color: #333;
border-radius: 3px;
z-index: 110;
margin: 8px 2px 5px 10px;
right: 0;
filter: drop-shadow(0 0 5px rgba(150, 150, 150, 0.75));
padding: 4px 12px;
padding-left: 5px;
&:after {
bottom: 100%;
right: 6px;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-color: rgba(238, 238, 238, 0);
border-bottom-color: #fff;
border-width: 10px;
}
&.jsxc_open {
display: block;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
border: 0;
cursor: auto;
}
a {
color: #000;
opacity: 0.5;
white-space: nowrap;
&:hover {
text-decoration: none;
opacity: 1;
}
&.jsxc_disabled {
text-decoration: line-through;
opacity: 0.5;
&:hover {
text-decoration: line-through;
opacity: 0.5;
}
span {
cursor: default;
}
}
}
.jsxc_icon {
width: 16px;
height: 16px;
margin-right: 8px;
display: inline-block;
background-repeat: no-repeat;
background-size: contain;
background-position: center;
vertical-align: sub;
}
}
.jsxc_editicon {
background-image: image-url("edit_black.svg");
}
.jsxc_deleteicon {
background-image: image-url("delete_black.svg");
}
.jsxc_chaticon {
background-image: image-url("speech_balloon_black.svg");
}
.jsxc_videoicon {
background-image: image-url("camera_icon_black.svg");
}
.jsxc_infoicon {
background-image: image-url("info_black.svg");
}
.jsxc_settingsicon {
background-image: image-url("gear_black.svg");
}
.jsxc_helpicon {
background-image: image-url("help_black.svg");
}
.jsxc_contacticon {
background-image: image-url("contact_black.svg");
}
.jsxc_groupcontacticon {
background-image: image-url("groupcontact_black.svg");
}
.jsxc_bookmarkicon {
background-image: image-url("bookmark_black.svg");
}
.jsxc_announcementicon {
background-image: image-url("megaphone_icon_black.svg");
}
.jsxc_more {
float: right;
width: 44px;
height: 100%;
cursor: pointer;
background-image: image-url("more_black.svg");
background-repeat: no-repeat;
background-position: center;
opacity: 0.4;
&:hover {
opacity: 1;
}
@media (min-width: 768px) {
width: 25px;
}
}
-399
Ver Arquivo
@@ -1,399 +0,0 @@
#jsxc_roster {
position: fixed;
top: 0;
bottom: 0;
right: 0;
width: 200px;
overflow: visible;
border-left: 1px solid #e1e1e1;
display: none;
// border-left: 1px solid $roster_border_left;
z-index: 80;
margin-left: 10px;
background-color: $roster_bg;
a {
cursor: pointer;
}
.slimScrollDiv {
margin-bottom: 30px;
z-index: 40;
}
.jsxc_wait {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 160px;
padding: 20px;
background-color: $white;
z-index: 60;
img {
padding: 5px;
}
h3 {
margin-bottom: 5px;
font-size: 1.13em;
font-weight: bold;
}
}
input {
position: absolute;
margin: 0;
height: 35px;
padding: 7px 6px 5px;
font-size: 13px;
width: 145px;
border: 1px solid #ddd;
box-sizing: border-box;
background-image: none;
background-color: $roster_input_bg;
border-radius: 3px;
box-shadow: inner 0 0 5px $roster_input_shadow;
outline: none;
}
p {
color: $roster_color;
padding: 10px;
a {
color: $roster_a;
text-decoration: underline;
}
}
.jsxc_avatar {
position: relative;
cursor: pointer;
img {
cursor: pointer;
}
}
.jsxc_expand input {
left: 51px;
width: 137px;
}
&.jsxc_noConnection {
.slimScrollDiv {
display: none;
}
> .jsxc_bottom {
display: none;
}
}
&.jsxc_state_hidden {
display: block;
right: -200px;
transition: right 0.5s;
#jsxc_toggleRoster {
&:before {
transform: rotate(0deg);
}
}
}
&.jsxc_state_shown {
display: block;
right: 0;
transition: right 0.5s;
}
> .jsxc_bottom {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
line-height: 34px;
background-color: $roster_bottom_bg;
z-index: 50;
padding-right: 4px;
&:hover {
background-color: $roster_bottom_bg_hover;
}
.jsxc_inner {
width: 100%;
}
ul {
padding: 0;
margin: 0;
width: 100%;
border-top: 1px solid $roster_bottom_border_top;
background-color: $roster_bottom_bg;
li:last-child {
border-bottom: 1px solid $roster_bottom_border_top;
}
}
li {
height: 44px;
background-color: $roster_bottom_bg;
color: $roster_bottom_color;
cursor: pointer;
width: 100%;
padding-left: 44px;
line-height: 44px;
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
background-repeat: no-repeat;
background-position: 15px center;
background-size: 16px 16px;
opacity: 0.8;
&.jsxc_disabled {
color: $roster_bottom_disabled;
cursor: default;
}
&:hover:not(.jsxc_disabled) {
color: $roster_bottom_color_hover;
background-color: $roster_bottom_bg_hover;
}
&.jsxc_warning {
background-color: $warning_bg;
&:hover {
background-color: $warning_bg_hover;
}
}
}
> div > span {
cursor: pointer;
}
}
}
#jsxc_toggleRoster {
width: 14px;
height: 100%;
position: absolute;
left: -14px !important;
top: 0;
z-index: 110;
background-color: transparent;
cursor: pointer;
&:hover {
background-color: $roster_toggle_hover;
}
&:before {
content: " ";
position: absolute;
display: block;
width: 0;
top: 50%;
right: 0;
border-style: solid;
border-width: 6px 4px 6px 0;
border-color: transparent $roster_bg;
transform: rotate(180deg);
}
}
.jsxc_rosteritem {
padding: 0;
margin: 0;
height: 44px;
border-bottom: 1px solid $roster_bottom_border_top;
cursor: pointer;
width: 100%;
position: relative;
color: $roster_color;
font-family: $font_sans;
line-height: 44px;
padding-left: 6px;
padding-top: 4px;
padding-bottom: 4px;
box-sizing: border-box;
&:hover {
background-color: $roster_bg_hover;
}
&.jsxc_bookmarked {
.jsxc_avatar:after {
content: " ";
width: 20%;
height: 30%;
position: absolute;
top: 0;
right: 2px;
background-size: contain;
background-repeat: no-repeat;
background-image: image-url("bookmark_red.svg");
}
}
}
.jsxc_caption {
padding-right: 30px;
height: 100%;
line-height: 100%;
// padding-top: 4px;
box-sizing: border-box;
* {
cursor: pointer;
}
.jsxc_name {
height: 100%;
line-height: 40px;
.jsxc_min & {
height: 50%;
line-height: 20px;
}
.jsxc_rosteritem & {
height: 50%;
line-height: 20px;
}
}
.jsxc_lastmsg {
font-size: 12px;
display: none;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
.jsxc_min & {
display: block;
height: 50%;
line-height: 17.5px;
}
.jsxc_rosteritem & {
display: block;
height: 50%;
line-height: 17.5px;
}
.jsxc_text {
opacity: 0.6;
}
.jsxc_unread {
line-height: 100%;
font-size: 8px;
color: #fff;
text-align: center;
display: none;
height: 1em;
width: 1em;
border-radius: 50%;
background-color: orange;
vertical-align: top;
margin: 0;
float: none;
.jsxc_unreadMsg & {
display: inline-block !important;
}
}
.jsxc_emoticon {
vertical-align: middle;
}
}
}
#jsxc_avatar {
cursor: default !important;
}
#jsxc_presence {
cursor: pointer;
padding-left: 2px;
overflow: hidden;
> span {
opacity: 0.8;
}
li {
position: relative;
&:before {
// Presence indicator
position: absolute;
top: 50%;
left: 10px;
margin-top: -8px;
border: 2px solid whitesmoke;
}
}
}
#jsxc_menu {
height: 44px;
width: 44px;
cursor: pointer;
float: right;
text-align: center;
&:hover > span {
opacity: 1;
}
> span {
opacity: 0.5;
display: block;
width: 100%;
height: 100%;
background-image: image-url("menu_black.svg");
background-repeat: no-repeat;
background-position: center 10px;
background-size: 17px;
}
@media (min-width: 768px) {
height: 30px;
width: 30px;
}
}
#jsxc_notice {
height: 30px;
width: 30px;
float: right;
text-align: center;
line-height: 30px;
span {
background-color: $notice_bg;
border-radius: 11px;
color: $notice_color;
font-size: 80%;
padding: 2px;
position: relative;
animation: bounce 2s 1s infinite;
}
> span:empty {
display: none;
}
}
-49
Ver Arquivo
@@ -1,49 +0,0 @@
.jsxc_online, .jsxc_chat, .jsxc_away, .jsxc_xa, .jsxc_dnd {
&:before {
content: " ";
display: block;
width: 12px;
height: 12px;
border-radius: 100%;
line-height: 12px;
text-align: center;
color: #fff;
z-index: 99;
background-repeat: no-repeat;
background-position: center;
background-size: 100%;
box-sizing: content-box;
}
}
.jsxc_online:before {
background-color: $state_online;
}
.jsxc_chat:before {
background-image: image-url("presence_chat.svg");
background-color: $state_chat;
}
.jsxc_away:before {
background-image: image-url("presence_away.svg");
background-color: $state_away;
}
.jsxc_xa:before {
background-image: image-url("presence_xa.svg");
background-color: $state_xa;
}
.jsxc_dnd:before {
background-image: image-url("presence_dnd.svg");
background-color: $state_dnd;
}
.jsxc_hidden {
display: none;
}
.jsxc_invalid {
border: 2px solid $invalid_border !important;
}
-706
Ver Arquivo
@@ -1,706 +0,0 @@
#jsxc_windowList {
position: fixed;
bottom: 0;
right: 210px;
left: 0;
z-index: 50;
transition: right 0.5s;
&.jsxc_roster_hidden {
right: 10px;
}
@media (min-width: 768px) {
clip: rect(-10000px, 10000px, 30px, 30px);
}
> ul {
list-style: none;
padding: 0;
margin: 0;
position: absolute;
bottom: 0;
right: 0;
height: 44px;
overflow: visible;
white-space: nowrap;
transition: right 0.5s;
> li {
padding: 0;
margin: 0;
display: inline-block;
height: 44px;
width: 46px;
position: relative;
overflow: visible;
margin-right: 5px;
cursor: pointer;
white-space: normal;
&.jsxc_normal {
transition: width 0.2s;
width: 250px;
}
&.jsxc_min {
transition: width 0.2s;
width: 46px !important;
// overwrite resizeable width
@media (min-width: 768px) {
width: 200px !important;
}
.jsxc_emoticons {
display: none;
}
.jsxc_tools {
display: none;
}
}
}
}
}
#jsxc_windowListSB {
position: fixed;
left: 0;
bottom: 0;
width: 30px;
height: 30px;
@media (max-width: 768px) {
display: none;
}
> {
div {
box-sizing: border-box;
width: 14px;
height: 100%;
background-color: $windowListSB_bg;
color: $windowListSB_color;
text-align: center;
line-height: 30px;
float: left;
cursor: pointer;
user-select: none;
&:hover {
background-color: $windowListSB_bg_hover;
}
}
.jsxc_disabled {
background-color: $windowListSB_bg_disabled !important;
color: $windowListSB_color_disabled;
cursor: default !important;
display: none;
}
}
}
.jsxc_bar {
background-color: $window_bar_bg;
cursor: pointer;
height: 44px;
line-height: 26px;
padding: 2px;
color: $window_bar_color;
width: 100%;
box-sizing: border-box;
position: relative;
&:hover {
.jsxc_normal & {
color: $window_bar_color_hover;
}
}
.jsxc_tools {
&:hover {
.jsxc_normal & {
color: #000;
}
}
}
.jsxc_min & {
background-color: $window_min_bar_bg;
color: $window_min_bar_color;
}
}
.jsxc_window {
position: absolute;
bottom: -284px;
top: auto;
left: 0;
right: 0;
height: auto;
background-color: $window_bg;
z-index: 80;
cursor: default;
border: 1px solid $window_border;
border-bottom: 0;
.jsxc_min & {
transition: bottom 0.2s;
}
.jsxc_normal & {
transition: bottom 0.2s;
}
.jsxc_showOverlay & {
.jsxc_overlay {
display: block !important;
}
}
.jsxc_emoticons {
height: 44px;
width: 44px;
position: absolute;
bottom: 0;
left: 0;
cursor: pointer;
&:after {
content: " ";
background-image: image-url("smiley.svg");
background-position: center center;
background-repeat: no-repeat;
background-size: 30px 30px;
opacity: 0.3;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.jsxc_inner {
left: 5px;
}
ul {
width: 210px;
margin-bottom: 8px;
background-color: $emoticon_selection_bg;
border-radius: 3px;
z-index: 200;
list-style-type: none;
padding: 3px;
position: relative;
&:after {
content: " ";
position: absolute;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid $emoticon_selection_bg;
display: block;
width: 0;
z-index: 1;
left: 7px;
top: 100%;
}
}
li {
div {
float: left;
cursor: pointer;
border-radius: 3px;
background-size: 30px 30px;
width: 30px;
height: 30px;
&:hover {
background-color: $emoticon_selection_hover;
}
}
}
&:hover:after {
opacity: 0.5;
}
}
.jsxc_fade {
position: relative;
.jsxc_overlay {
display: none;
background-color: rgba(0, 0, 0, 0.5);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
overflow-y: scroll;
> div {
background-color: #fff;
margin: 30px 10px;
padding: 5px;
border-radius: 3px;
text-align: center;
position: relative;
.jsxc_close {
position: absolute;
top: 0;
right: 0;
height: 44px;
width: 44px;
&:after {
content: "×";
position: absolute;
top: 4px;
right: 4px;
font-size: 20px;
font-family: Arial, sans-serif;
cursor: pointer;
color: #000;
opacity: 0.4;
}
&:hover {
&:after {
opacity: 1;
}
}
@media (min-width: 768px) {
width: 30px;
height: 30px;
}
}
.jsxc_body {
margin-top: 20px;
}
p {
margin-bottom: 10px;
}
li {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
a:hover {
text-decoration: underline;
}
}
}
}
.jsxc_avatar {
margin-top: 1px;
}
.jsxc_textarea {
width: 100%;
overflow: hidden;
padding: 3px;
}
.slimScrollDiv {
margin: 0 0 6px;
left: auto !important;
top: auto !important;
}
textarea {
&.jsxc_textinput {
width: 100%;
height: 44px;
margin: 0;
padding: 14px 40px 12px;
outline: none;
border-radius: 0;
box-sizing: border-box;
border: 0;
display: block;
resize: none;
transition: height 0.5s;
font-size: 13px;
}
&::placeholder {
color: $window_placeholder;
opacity: 0.3;
}
}
.jsxc_tools {
float: right;
> .jsxc_disabled {
opacity: 0.3;
cursor: default !important;
}
> div {
width: 25px;
height: 40px;
display: block;
float: left;
color: $tools_color;
opacity: 0.4;
font-family: $font_sans;
line-height: 40px;
cursor: pointer;
text-align: center;
&.jsxc_settings {
opacity: 1;
}
}
}
.jsxc_close {
font-size: 20px;
&:hover {
color: $window_close_hover;
opacity: 1;
}
}
.jsxc_more {
background-image: image-url("more_white.svg");
opacity: 0.4;
}
.ui-resizable-w {
left: 0;
}
.ui-resizable-nw {
top: 0;
left: 0;
width: 15px;
height: 15px;
z-index: 95 !important;
background-image: image-url("resize_gray.svg");
}
.ui-resizable-n {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 15px;
z-index: 100;
}
}
.jsxc_chatmessage {
margin: 3px;
padding: 4px;
word-wrap: break-word;
background-color: $chatmessage_bg;
position: relative;
outline: none;
clear: both;
&.jsxc_error {
opacity: 0.7;
&:before {
content: " ";
position: absolute;
top: 3px;
right: 3px;
width: 8px;
height: 8px;
background-color: yellow;
}
}
a {
color: $chatmessage_a;
text-decoration: underline;
display: inline-block;
max-width: 100%;
position: relative;
&[download]:before {
content: " ";
position: absolute;
top: 0;
right: 0;
bottom: 5px;
left: 0;
border-radius: 3px;
background-color: rgba(255, 255, 255, 0.7);
background-image: url("../img/download_icon_black.svg");
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
opacity: 0;
transition: opacity 0.5s;
}
&[download]:hover {
&:before {
opacity: 0.6;
}
}
}
img {
max-width: 100%;
}
.jsxc_avatar {
display: none;
}
.jsxc_attachment {
border-radius: 3px;
background-color: #fff;
padding: 3px;
padding-left: 30px;
min-height: 30px;
margin-bottom: 5px;
background-position: 3px center;
background-size: 25px 25px;
background-repeat: no-repeat;
background-image: image-url("filetypes/file.svg");
img {
border-radius: 3px;
}
&.jsxc_image {
line-height: 0;
padding: 0;
background-image: url("");
display: inline-block;
}
&.jsxc_application {
background-image: image-url("filetypes/application.svg");
}
&.jsxc_application-pdf {
background-image: image-url("filetypes/application-pdf.svg");
}
&.jsxc_audio {
background-image: image-url("filetypes/audio.svg");
}
&.jsxc_video {
background-image: image-url("filetypes/video.svg");
opacity: 1;
}
&.jsxc_text {
background-image: image-url("filetypes/text.svg");
}
}
}
.jsxc_timestamp {
font-size: 8px;
color: $chatmessage_timestamp;
line-height: 8px;
overflow: hidden;
white-space: nowrap;
max-width: 100%;
text-overflow: ellipsis;
clear: both;
}
.jsxc_encrypted {
&.jsxc_received.jsxc_out .jsxc_timestamp {
margin-right: 1px;
}
.jsxc_timestamp:after {
content: " ";
display: inline-block;
width: 10px;
height: 8px;
margin-left: 2px;
background-image: image-url("padlock_close_grey.svg");
background-size: contain;
background-repeat: no-repeat;
}
}
.jsxc_in {
float: left;
position: relative;
max-width: 76%;
margin-left: 10px;
border-radius: 3px;
background-color: $chatmessage_in_bg;
&:after {
content: " ";
position: absolute;
border-style: solid;
border-width: 5px 6px 5px 0;
border-color: transparent $chatmessage_in_bg;
display: block;
width: 0;
z-index: 1;
left: -6px;
bottom: 10px;
}
.jsxc_timestamp {
float: left;
}
}
.jsxc_out {
float: right;
position: relative;
max-width: 76%;
margin-right: 10px;
padding-right: 10px;
border-radius: 3px;
background-color: $chatmessage_out_bg;
&:after {
content: " ";
position: absolute;
border-style: solid;
border-width: 5px 0 5px 6px;
border-color: transparent $chatmessage_out_bg;
display: block;
width: 0;
z-index: 1;
right: -6px;
bottom: 10px;
}
&.jsxc_received {
&:before {
content: "";
position: absolute;
bottom: 2px;
right: 2px;
font-size: 12px;
line-height: 12px;
color: $chatmessage_received;
}
.jsxc_timestamp {
margin-right: 4px;
}
}
.jsxc_timestamp {
float: right;
}
}
.jsxc_sys {
width: auto;
max-width: none;
padding-right: 4px;
box-sizing: border-box;
margin-right: 3px;
border-radius: 3px;
background-color: transparent;
font-size: 0.8em;
font-style: italic;
.jsxc_emoticon {
width: 1.2em;
height: 1.2em;
vertical-align: middle;
}
&.jsxc_composing {
text-align: center;
font-size: 0.9em;
font-style: italic;
display: block;
opacity: 0;
overflow: hidden;
transition: opacity 0.6s;
&:before {
content: " ";
width: 1.5em;
height: 1em;
display: inline-block;
background-size: 80%;
background-repeat: no-repeat;
margin: 0 3px 0 0;
background-image: image-url("composing.png");
}
&.jsxc_fadein {
opacity: 1;
}
}
}
div.jsxc_settings {
position: relative;
.jsxc_inner {
left: auto;
top: 100%;
right: -6px;
}
}
div.jsxc_transfer {
background-image: image-url("padlock_open_black.svg");
background-repeat: no-repeat;
background-position: center center;
background-size: 14px 14px;
opacity: 0.3;
height: 44px;
width: 44px;
position: absolute;
bottom: 0;
right: 0;
cursor: pointer;
&:hover {
opacity: 1;
}
&.jsxc_disabled {
background-image: image-url("padlock_open_disabled_black.svg");
cursor: default;
&:hover {
opacity: 0.3;
}
}
&.jsxc_fin {
opacity: 1;
background-image: image-url("padlock_close_grey.svg");
}
&.jsxc_enc {
opacity: 1;
background-image: image-url("padlock_close_orange.svg");
&.jsxc_trust {
background-image: image-url("padlock_close_green.svg");
}
}
}
-17
Ver Arquivo
@@ -1,17 +0,0 @@
@import "colors";
@import "dep";
//fonts
$font_sans: Arial, sans-serif;
$font_serif: serif;
@import "modules";
@import "buddylist";
@import "state";
@import "emoticons";
@import "roster";
@import "window";
@import "muc";
@import "_jsxc";
@import "webrtc";
+20
Ver Arquivo
@@ -0,0 +1,20 @@
@import "modules/all";
@import "vendor/all";
//fonts
$font_sans: Arial, sans-serif;
$font_serif: serif;
@import "partials/button";
@import "partials/dialog";
@import "partials/emoticons";
@import "partials/icon";
@import "partials/jsxc";
@import "partials/menu";
@import "partials/roster";
@import "partials/webrtc";
@import "partials/window-list";
@import "partials/window";
@import "partials/jsxc";
@import "partials/webrtc";
+5
Ver Arquivo
@@ -0,0 +1,5 @@
@import "animation";
@import "colors";
@import "muc";
@import "webrtc";
@import "presence";
@@ -25,12 +25,23 @@ $dialog_input_invalid: $red;
$dialog_input_readonly_bg: $gray90;
$spot_bg: $white;
$spot_border: $black;
$state_online: green;
$state_chat: green;
$state_away: $orange;
$state_xa: $orange;
$state_dnd: $red;
$state_offline: $gray60;
$presenceColors: (
online: green,
chat: green,
away: $orange,
xa: $orange,
dnd: $red,
offline: $gray60
);
$notice_bg: $orange;
$notice_color: $black;
$window_unread_cycle: $orange;
+6
Ver Arquivo
@@ -0,0 +1,6 @@
%muc-avatar-icon {
text-indent: 999px;
background-image: url("../img/group_white.svg");
background-size: 70% 70% !important;
background-repeat: no-repeat;
}
+26
Ver Arquivo
@@ -0,0 +1,26 @@
$presences: online chat away xa dnd;
@mixin presenceIndicator($target) {
@each $presence in $presences {
[data-presence="#{$presence}"] #{$target} {
&:before {
content: "";
display: block;
width: 12px;
height: 12px;
border-radius: 100%;
line-height: 12px;
text-align: center;
color: #fff;
z-index: 99;
background-repeat: no-repeat;
background-position: center;
background-size: 100%;
box-sizing: content-box;
background-image: url("../img/presence_#{$presence}.svg");
background-color: map-get($presenceColors, $presence);
}
}
}
}
+9
Ver Arquivo
@@ -0,0 +1,9 @@
%fullscreen {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 9000;
background-color: $fullscreen_bg;
}
+47
Ver Arquivo
@@ -0,0 +1,47 @@
.jsxc-btn {
width: auto;
min-width: 25px;
display: inline-block;
padding: 6px 12px;
margin: 0 2px;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
transition: background-color 0.5s;
&.jsxc-btn-default {
border-color: #ccc;
color: #555;
background-color: rgba(240, 240, 240, 0.9);
&:hover {
background-color: #d6d6d6;
}
}
&.jsxc-btn-primary {
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
&:hover {
background-color: #296496;
}
}
&[disabled], &[disabled]:hover {
opacity: 0.65;
cursor: not-allowed;
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
}
}
+127
Ver Arquivo
@@ -0,0 +1,127 @@
.jsxc-dialog {
padding: 20px;
min-width: 320px;
max-width: 100%;
display: inline-block;
text-align: left;
position: relative;
background: #FFF;
width: auto;
* {
box-sizing: border-box;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
margin: 0;
padding: 0;
}
p {
margin-bottom: 1em;
input {
margin-bottom: 5px;
width: 60%;
outline: none;
}
input[type='submit'] {
width: auto;
}
}
table {
margin-bottom: 1em;
}
hr {
border: 0;
border-top: 1px solid #eee;
margin-top: 20px;
margin-bottom: 20px;
}
h3 {
font-size: 120%;
font-weight: bold;
margin-bottom: 10px;
margin-top: 20px;
}
.jsxc-right {
margin-top: 20px;
}
form {
fieldset {
margin-bottom: 30px;
padding: 0 30px;
border: 1px solid #d9d9d9;
h3 {
font-size: 15px;
color: #000;
background-color: #f2f2f2;
padding: 10px;
margin: 0 -30px 10px;
}
}
}
legend {
border: 0;
font-size: 20px;
}
input {
outline: none;
&:invalid {
border: 1px solid $dialog_input_invalid;
}
}
.btn-group button {
margin-right: 0;
}
input[readonly] {
background-color: $dialog_input_readonly_bg;
}
.jsxc-inputinfo {
padding: 0;
font-style: italic;
margin: 0;
}
.jsxc-waiting {
&:before {
content: " ";
width: 1em;
height: 1em;
display: inline-block;
background-size: 100%;
margin: 0 3px 0 0;
background-image: url("../img/loading.gif");
}
}
.jsxc-libraries, .jsxc-credits {
max-width: 300px;
}
.jsxc-warning {
display: block;
background-color: #fbfe7a;
padding: 3px 10px;
border-radius: 3px;
}
}
@@ -1,4 +1,4 @@
.jsxc_emoticon {
.jsxc-emoticon {
display: inline-block;
width: 19px;
height: 19px;
@@ -6,14 +6,14 @@
border: 0;
vertical-align: bottom;
&.jsxc_large {
&.jsxc-large {
width: 40px;
height: 40px;
margin-bottom: 7px;
}
}
#jsxc_roster .jsxc_emoticon.jsxc_large {
#jsxc-roster .jsxc-emoticon.jsxc-large {
width: 19px;
height: 19px;
}
@@ -21,7 +21,7 @@
$emoticons: angel, angry, smile, grin, sad, wink, tonguesmile, surpised, kiss, sunglassess, crysad, doubt, zip, thumbsup, thumbsdown, beer, devil, kissing, rose, music, love, tired, surprised;
@each $emoticon in $emoticons {
.jsxc_#{$emoticon} {
background: image-url("emotions/#{$emoticon}.png");
.jsxc-#{$emoticon} {
background: url("../img/emotions/#{$emoticon}.png");
}
}
+43
Ver Arquivo
@@ -0,0 +1,43 @@
.jsxc-icon-edit {
background-image: url("../img/edit_black.svg");
}
.jsxc-icon-delete {
background-image: url("../img/delete_black.svg");
}
.jsxc-icon-chat {
background-image: url("../img/speech_balloon_black.svg");
}
.jsxc-icon-video {
background-image: url("../img/camera_icon_black.svg");
}
.jsxc-icon-info {
background-image: url("../img/info_black.svg");
}
.jsxc-icon-setting {
background-image: url("../img/gear_black.svg");
}
.jsxc-icon-help {
background-image: url("../img/help_black.svg");
}
.jsxc-icon-contact {
background-image: url("../img/contact_black.svg");
}
.jsxc-icon-groupcontact {
background-image: url("../img/groupcontact_black.svg");
}
.jsxc-icon-bookmark {
background-image: url("../img/bookmark_black.svg");
}
.jsxc-icon-announcement {
background-image: url("../img/megaphone_icon_black.svg");
}
+209
Ver Arquivo
@@ -0,0 +1,209 @@
.jsxc-right {
text-align: right;
}
.jsxc-center {
text-align: center;
}
.jsxc-hidden {
display: none;
}
.jsxc-clear {
clear: both;
}
.jsxc-uppercase {
text-transform: uppercase;
}
.jsxc-separator {
border-top: 1px solid $separator;
}
.jsxc-name {
overflow: hidden;
cursor: pointer;
text-overflow: ellipsis;
white-space: nowrap;
}
.jsxc-max-width {
max-width: 500px;
}
.jsxc-meta {
text-align: right;
font-style: italic;
}
.jsxc-invalid {
border: 2px solid $invalid_border !important;
}
.jsxc-avatar {
width: 36px;
height: 36px;
line-height: 36px;
margin: 0 5px;
background-color: $avatar_bg;
border-radius: 50%;
float: left;
text-align: center;
font-weight: bold;
font-size: 30px;
color: $avatar_color;
position: relative;
font-family: $font_sans;
background-size: cover;
background-position: center center;
img {
display: block;
width: 25px;
height: 25px;
position: absolute;
top: 0;
left: 0;
}
&:before {
position: absolute;
top: -2px;
left: -6px;
border: 2px solid $roster_bg;
}
}
ul.jsxc-vCard {
min-width: 400px;
ul {
margin-left: 20px;
}
li {
cursor: default !important;
}
}
// Spot which is attached to xmpp: uris
.jsxc-spot {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
text-indent: -99999em;
margin-top: 3px;
margin-right: 5px;
line-height: 100%;
cursor: pointer;
border: 1px solid $spot_border;
background-color: $white;
&:before {
position: absolute;
}
&.jsxc-online, &.jsxc-chat, &.jsxc-away, &.jsxc-xa, &.jsxc-dnd, &.jsxc-offline {
border: 0;
}
}
.jsxc-unread {
display: none;
}
.jsxc-unreadMsg {
.jsxc-name {
font-style: italic;
}
.jsxc-unread {
display: block;
background-color: $unread_bg;
border-radius: 11px;
color: $unread_color;
font-size: 80%;
padding: 2px;
line-height: 15px;
float: right;
margin-right: 3px;
margin-top: 4px;
}
}
.jsxc-loading {
margin: 0 auto;
width: 32px;
height: 32px;
border: 0;
background-size: 32px 32px !important;
background: url("../img/loading.gif");
}
// @TODO: check
#jsxc-login-form input[type='submit'] {
height: 34px;
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: normal;
line-height: 1.428571429;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
border: 1px solid transparent;
border-radius: 4px;
user-select: none;
color: $white;
background-color: $loginForm_bg;
border-color: $loginForm_border;
}
.jsxc-oneway .jsxc-avatar {
filter: grayscale(100%);
}
img.jsxc-vCard {
float: right;
max-width: 200px;
max-height: 200px;
border: 5px solid $white;
border-radius: 2px;
}
.jsxc-alert {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
&.jsxc-alert-warning {
color: #8a6d3b;
background-color: #fcf8e3;
border-color: #faebcc;
}
}
.jsxc-more {
float: right;
width: 44px;
height: 100%;
cursor: pointer;
background-image: url("../img/more_black.svg");
background-repeat: no-repeat;
background-position: center;
opacity: 0.4;
&:hover {
opacity: 1;
}
@media (min-width: 768px) {
width: 25px;
}
}
+102
Ver Arquivo
@@ -0,0 +1,102 @@
.jsxc-menu {
.jsxc-inner {
box-sizing: border-box;
max-height: 0;
transition: max-height 0.5s;
overflow: hidden;
visibility: hidden;
position: absolute;
bottom: 100%;
left: 0;
}
&.jsxc-opened {
.jsxc-inner {
max-height: 1000px;
visibility: visible;
display: block;
}
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
border: 0;
cursor: auto;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
}
.jsxc-menu-dropdown {
.jsxc-inner {
display: none;
position: absolute;
background-color: #FFF;
color: #333;
border-radius: 3px;
z-index: 110;
margin: 8px 2px 5px 10px;
right: 0;
filter: drop-shadow(0 0 5px rgba(150, 150, 150, 0.75));
padding: 4px 12px 4px 5px;
top: 100%;
bottom: auto;
overflow: visible;
&:after {
bottom: 100%;
right: 6px;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-color: rgba(238, 238, 238, 0);
border-bottom-color: #fff;
border-width: 10px;
}
}
a {
color: #000;
opacity: 0.5;
white-space: nowrap;
&:hover {
text-decoration: none;
opacity: 1;
}
&.jsxc-disabled {
text-decoration: line-through;
opacity: 0.5;
&:hover {
text-decoration: line-through;
opacity: 0.5;
}
span {
cursor: default;
}
}
}
.jsxc-icon {
width: 16px;
height: 16px;
margin-right: 8px;
display: inline-block;
background-repeat: no-repeat;
background-size: contain;
background-position: center;
vertical-align: sub;
}
}
+18 -25
Ver Arquivo
@@ -1,22 +1,15 @@
%muc-avatar-icon {
text-indent: 999px;
background-image: image-url("group_white.svg");
background-size: 70% 70% !important;
background-repeat: no-repeat;
}
.jsxc_windowItem {
&.jsxc_groupchat.jsxc_normal {
.jsxc_fade {
.jsxc-window-item {
&.jsxc-groupchat.jsxc-normal {
.jsxc-fade {
padding-top: 44px;
}
.jsxc_fingerprints, .jsxc_verification, .jsxc_transfer, .jsxc_video, .jsxc_sendFile {
.jsxc-fingerprints, .jsxc-verification, .jsxc-transfer, .jsxc-video, .jsxc-sendFile {
display: none;
}
.jsxc_members {
background-image: image-url("group_white.svg");
.jsxc-members {
background-image: url("../img/group_white.svg");
background-size: 15px 15px;
background-repeat: no-repeat;
background-position: center;
@@ -26,10 +19,10 @@
}
}
.jsxc_chatmessage.jsxc_in {
.jsxc-chatmessage.jsxc-in {
margin-left: 50px;
.jsxc_avatar {
.jsxc-avatar {
display: block;
position: absolute;
bottom: 0;
@@ -42,14 +35,14 @@
}
}
.jsxc_bar {
.jsxc_avatar {
.jsxc-bar {
.jsxc-avatar {
@extend %muc-avatar-icon;
}
}
}
.jsxc_memberlist {
.jsxc-memberlist {
height: 44px;
width: 100%;
background-color: $window_bar_bg;
@@ -79,18 +72,18 @@
margin-right: 2px;
}
.jsxc_name {
.jsxc-name {
display: none;
}
.jsxc_avatar {
.jsxc-avatar {
margin-left: 2px;
margin-right: 0;
}
}
}
&.jsxc_expand {
&.jsxc-expand {
ul {
white-space: normal;
@@ -100,7 +93,7 @@
height: 40px;
line-height: 40px;
.jsxc_name {
.jsxc-name {
display: block;
cursor: default;
@@ -109,7 +102,7 @@
}
}
.jsxc_avatar {
.jsxc-avatar {
margin-right: 4px;
}
}
@@ -119,11 +112,11 @@
}
li[data-type='groupchat'] {
.jsxc_avatar {
.jsxc-avatar {
@extend %muc-avatar-icon;
}
.jsxc_video {
.jsxc-video {
display: none;
}
}
+492
Ver Arquivo
@@ -0,0 +1,492 @@
#jsxc-roster {
position: fixed;
top: 0;
bottom: 0;
right: 0;
width: 200px;
overflow: visible;
border-left: 1px solid #e1e1e1;
z-index: 80;
margin-left: 10px;
background-color: $roster_bg;
transition: right 0.5s;
.jsxc-roster-hidden & {
right: -200px;
}
a {
cursor: pointer;
}
.jsxc-avatar {
position: relative;
cursor: pointer;
img {
cursor: pointer;
}
}
.jsxc-wait {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 160px;
padding: 20px;
background-color: $white;
z-index: 60;
img {
padding: 5px;
}
h3 {
margin-bottom: 5px;
font-size: 1.13em;
font-weight: bold;
}
}
input {
position: absolute;
margin: 0;
height: 35px;
padding: 7px 6px 5px;
font-size: 13px;
width: 145px;
border: 1px solid #ddd;
box-sizing: border-box;
background-image: none;
background-color: $roster_input_bg;
border-radius: 3px;
box-shadow: inner 0 0 5px $roster_input_shadow;
outline: none;
}
p {
color: $roster_color;
padding: 10px;
a {
color: $roster_a;
text-decoration: underline;
}
}
.jsxc-expand input {
left: 51px;
width: 137px;
}
&.jsxc-state_hidden {
display: block;
right: -200px;
transition: right 0.5s;
}
&.jsxc-state_shown {
display: block;
right: 0;
transition: right 0.5s;
}
> .jsxc-bottom {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
line-height: 34px;
background-color: $roster_bottom_bg;
z-index: 50;
padding-right: 4px;
&:hover {
background-color: $roster_bottom_bg_hover;
}
.jsxc-inner {
width: 100%;
}
ul {
padding: 0;
margin: 0;
width: 100%;
border-top: 1px solid $roster_bottom_border_top;
background-color: $roster_bottom_bg;
li:last-child {
border-bottom: 1px solid $roster_bottom_border_top;
}
}
li {
height: 44px;
background-color: $roster_bottom_bg;
color: $roster_bottom_color;
cursor: pointer;
width: 100%;
padding-left: 44px;
line-height: 44px;
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
background-repeat: no-repeat;
background-position: 15px center;
background-size: 16px 16px;
opacity: 0.8;
&.jsxc-disabled {
color: $roster_bottom_disabled;
cursor: default;
}
&:hover:not(.jsxc-disabled) {
color: $roster_bottom_color_hover;
background-color: $roster_bottom_bg_hover;
}
&.jsxc-warning {
background-color: $warning_bg;
&:hover {
background-color: $warning_bg_hover;
}
}
}
> div > span {
cursor: pointer;
}
}
form {
padding: 15px;
button,
input {
width: 100%;
margin: 0 0 5px;
border-radius: 0;
}
.btn-primary {
background-color: #dadada;
border-color: #c1c1c1;
transition: background-color 0.5s;
&:hover {
background-color: #a2a2a2;
}
}
label {
display: block;
}
input {
position: static;
}
}
.jsxc-roster-status {
display: none;
position: absolute;
bottom: 0;
}
&.jsxc-status-show {
.jsxc-roster-status {
display: block;
}
.jsxc-bottom, .jsxc-contact-list {
display: none;
}
}
}
.jsxc-roster-toggle {
width: 14px;
height: 100%;
position: absolute;
left: -14px;
top: 0;
z-index: 110;
background-color: transparent;
cursor: pointer;
&:hover {
background-color: $roster_toggle_hover;
}
}
.jsxc-roster-item {
padding: 0;
margin: 0;
height: 44px;
border-bottom: 1px solid $roster_bottom_border_top;
cursor: pointer;
width: 100%;
position: relative;
color: $roster_color;
font-family: $font_sans;
line-height: 44px;
padding-left: 6px;
padding-top: 4px;
padding-bottom: 4px;
box-sizing: border-box;
&:hover {
background-color: $roster_bg_hover;
}
&.jsxc-bookmarked {
.jsxc-avatar:after {
content: " ";
width: 20%;
height: 30%;
position: absolute;
top: 0;
right: 2px;
background-size: contain;
background-repeat: no-repeat;
background-image: url("../img/bookmark_red.svg");
}
}
}
.jsxc-caption {
padding-right: 30px;
height: 100%;
line-height: 100%;
// padding-top: 4px;
box-sizing: border-box;
* {
cursor: pointer;
}
.jsxc-name {
height: 100%;
line-height: 40px;
.jsxc-min & {
height: 50%;
line-height: 20px;
}
.jsxc-rosteritem & {
height: 50%;
line-height: 20px;
}
}
.jsxc-lastmsg {
font-size: 12px;
display: none;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
.jsxc-min & {
display: block;
height: 50%;
line-height: 17.5px;
}
.jsxc-rosteritem & {
display: block;
height: 50%;
line-height: 17.5px;
}
.jsxc-text {
opacity: 0.6;
}
.jsxc-unread {
line-height: 100%;
font-size: 8px;
color: #fff;
text-align: center;
display: none;
height: 1em;
width: 1em;
border-radius: 50%;
background-color: orange;
vertical-align: top;
margin: 0;
float: none;
.jsxc-unreadMsg & {
display: inline-block !important;
}
}
.jsxc-emoticon {
vertical-align: middle;
}
}
}
.jsxc-menu-presence {
cursor: pointer;
padding-left: 2px;
overflow: hidden;
> span {
opacity: 0.8;
}
li {
position: relative;
&:before {
// Presence indicator
position: absolute;
top: 50%;
left: 10px;
margin-top: -8px;
border: 2px solid whitesmoke;
}
}
}
.jsxc-menu-main {
height: 44px;
width: 44px;
cursor: pointer;
float: right;
text-align: center;
&:hover > span {
opacity: 1;
}
> span {
opacity: 0.5;
display: block;
width: 100%;
height: 100%;
background-image: url("../img/menu_black.svg");
background-repeat: no-repeat;
background-position: center 10px;
background-size: 17px;
}
@media (min-width: 768px) {
height: 30px;
width: 30px;
}
}
#jsxc-notice {
height: 30px;
width: 30px;
float: right;
text-align: center;
line-height: 30px;
span {
background-color: $notice_bg;
border-radius: 11px;
color: $notice_color;
font-size: 80%;
padding: 2px;
position: relative;
animation: bounce 2s 1s infinite;
}
> span:empty {
display: none;
}
}
.jsxc-contact-list {
@include presenceIndicator(".jsxc-avatar");
list-style: none;
padding: 0;
margin: 0;
width: 204px;
z-index: 85;
&.jsxc-hide-offline {
.jsxc-roster-item[data-status='offline'] {
display: none;
}
}
.jsxc-unreadMsg {
.jsxc-name {
padding-right: 0;
}
}
.jsxc-oneway {
.jsxc-avatar,
.jsxc-caption {
opacity: 0.7;
}
}
.jsxc-right {
float: right;
margin-right: 6px;
div {
font-weight: bold;
text-align: center;
font-size: 13px;
line-height: 20px;
color: $white;
&:hover {
opacity: 1;
}
}
}
.jsxc-menu {
float: right;
height: 100%;
width: 42px;
> span {
display: block;
height: 100%;
width: 100%;
background-image: url("../img/more_black.svg");
background-repeat: no-repeat;
background-position: center center;
opacity: 0.6;
cursor: pointer;
&:hover {
opacity: 1;
}
}
.jsxc-inner {
left: auto;
right: 5px;
padding: 4px;
overflow: visible;
a {
display: block;
line-height: 42px;
width: 42px;
text-align: center;
span {
margin: 0;
}
}
}
}
}
+49 -60
Ver Arquivo
@@ -1,16 +1,5 @@
@import "colors";
%fullscreen {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 9000;
background-color: $fullscreen_bg;
}
#jsxc_webrtc {
#jsxc-webrtc {
position: fixed;
top: 0;
bottom: 0;
@@ -19,7 +8,7 @@
z-index: 9999;
background-color: black;
.jsxc_status {
.jsxc-status {
z-index: 9999;
border-radius: 20px;
display: none;
@@ -37,7 +26,7 @@
opacity: 1 !important;
}
li .jsxc_name {
li .jsxc-name {
cursor: auto;
&:hover {
@@ -46,7 +35,7 @@
}
}
.jsxc_establishing, .jsxc_ringing {
.jsxc-establishing, .jsxc-ringing {
&:after {
content: " ";
position: absolute;
@@ -62,14 +51,14 @@
$establishingColor1: #a1a1a1;
$establishingColor2: #f1f1f1;
.jsxc_establishing:before {
.jsxc-establishing:before {
content: " ";
display: block;
width: 40px;
height: 10px;
box-sizing: border-box;
background-color: $establishingColor1;
animation-name: jsxc_establishing;
animation-name: jsxc-establishing;
animation-duration: 2s;
animation-iteration-count: infinite;
position: absolute;
@@ -80,7 +69,7 @@ $establishingColor2: #f1f1f1;
margin-top: -5px;
}
@keyframes jsxc_establishing {
@keyframes jsxc-establishing {
0% {
border-width: 0;
background-color: $establishingColor1;
@@ -105,7 +94,7 @@ $establishingColor2: #f1f1f1;
$ringingColor1: #98d48f;
$ringingColor2: #76ba6c;
.jsxc_ringing:before {
.jsxc-ringing:before {
content: " ";
display: block;
width: 20px;
@@ -113,7 +102,7 @@ $ringingColor2: #76ba6c;
box-sizing: border-box;
background-color: $ringingColor1;
border-radius: 50%;
animation-name: jsxc_ringing;
animation-name: jsxc-ringing;
animation-duration: 2s;
animation-iteration-count: infinite;
position: absolute;
@@ -124,7 +113,7 @@ $ringingColor2: #76ba6c;
margin-top: -10px;
}
@keyframes jsxc_ringing {
@keyframes jsxc-ringing {
0% {
background-color: $ringingColor1;
width: 20px;
@@ -150,17 +139,17 @@ $ringingColor2: #76ba6c;
}
}
.jsxc_bell:before {
.jsxc-bell:before {
content: " ";
display: block;
width: 80px;
height: 80px;
box-sizing: border-box;
background-image: image-url("bell.svg");
background-image: url("../img/bell.svg");
background-size: contain;
background-position: center;
background-repeat: no-repeat;
animation-name: jsxc_ringing;
animation-name: jsxc-ringing;
animation-duration: 1.5s;
animation-iteration-count: infinite;
position: absolute;
@@ -171,7 +160,7 @@ $ringingColor2: #76ba6c;
margin-top: -40px;
}
@keyframes jsxc_bell {
@keyframes jsxc-bell {
0% {
margin-left: -50px;
}
@@ -205,7 +194,7 @@ $ringingColor2: #76ba6c;
}
}
.jsxc_videoContainer {
.jsxc-videoContainer {
position: absolute;
top: 0;
left: 0;
@@ -213,7 +202,7 @@ $ringingColor2: #76ba6c;
bottom: 0;
background-color: $video_bg;
&.jsxc_minimized {
&.jsxc-minimized {
position: fixed;
top: 10px;
left: 10px;
@@ -223,7 +212,7 @@ $ringingColor2: #76ba6c;
background-color: transparent;
box-shadow: 0 0 10px #a1a1a1;
.jsxc_localvideo {
.jsxc-localvideo {
position: static;
display: block;
}
@@ -233,30 +222,30 @@ $ringingColor2: #76ba6c;
display: none;
}
.jsxc_noRemoteVideo {
.jsxc-noRemoteVideo {
display: none;
}
@media (min-width: 768px) {
right: 250px;
.jsxc_controlbar {
.jsxc-controlbar {
opacity: 0;
}
&:hover {
.jsxc_controlbar {
.jsxc-controlbar {
opacity: 1;
}
}
}
}
.jsxc_remotevideo {
.jsxc-remotevideo {
@extend %fullscreen;
}
.jsxc_noRemoteVideo {
.jsxc-noRemoteVideo {
@extend %fullscreen;
p {
@@ -303,7 +292,7 @@ $ringingColor2: #76ba6c;
}
}
.jsxc_localvideo {
.jsxc-localvideo {
width: 160px;
height: 120px;
position: absolute;
@@ -320,7 +309,7 @@ div {
height: 100%;
background-color: $black;
&.jsxc_localvideo {
&.jsxc-localvideo {
border: 1px solid $white;
}
}
@@ -330,23 +319,23 @@ div {
height: 100%;
background-color: $black;
&.jsxc_localvideo {
&.jsxc-localvideo {
border: 1px solid $white;
}
}
&.jsxc_video {
background-image: image-url("camera_icon_white.svg");
&.jsxc-video {
background-image: url("../img/camera_icon_white.svg");
background-repeat: no-repeat;
background-position: center center;
background-size: 15px 15px;
opacity: 0.4;
&.jsxc_disabled {
background-image: image-url("camera_disabled_icon_white.svg");
&.jsxc-disabled {
background-image: url("../img/camera_disabled_icon_white.svg");
}
&:not(.jsxc_disabled) {
&:not(.jsxc-disabled) {
&:hover {
opacity: 1;
}
@@ -354,7 +343,7 @@ div {
}
}
.jsxc_controlbar {
.jsxc-controlbar {
position: absolute;
top: 50px;
left: 0;
@@ -369,7 +358,7 @@ div {
top: initial;
}
&.jsxc_visible {
&.jsxc-visible {
opacity: 1;
}
@@ -381,7 +370,7 @@ div {
display: inline-block;
}
.jsxc_videoControl {
.jsxc-videoControl {
height: 44px;
width: 44px;
margin: 0 5px;
@@ -397,24 +386,24 @@ div {
}
}
.jsxc_hangUp {
background-image: image-url("hang_up_red.svg");
.jsxc-hangUp {
background-image: url("../img/hang_up_red.svg");
}
.jsxc_fullscreen {
background-image: image-url("fullscreen_white.svg");
.jsxc-fullscreen {
background-image: url("../img/fullscreen_white.svg");
}
.jsxc_showchat {
.jsxc-showchat {
float: right;
}
}
.jsxc_multi > div {
.jsxc-multi > div {
display: none;
}
.jsxc_snapshotbar {
.jsxc-snapshotbar {
width: 100%;
display: none;
@@ -423,7 +412,7 @@ div {
}
}
.jsxc_buttongroup {
.jsxc-buttongroup {
display: inline;
button {
@@ -441,7 +430,7 @@ div {
}
}
.jsxc_chatarea {
.jsxc-chatarea {
position: absolute;
top: 0;
right: 0;
@@ -454,21 +443,21 @@ div {
display: block;
}
.jsxc_settings {
.jsxc-settings {
display: none !important;
}
.jsxc_close {
.jsxc-close {
display: none !important;
}
.jsxc_video {
.jsxc-video {
display: none !important;
}
.jsxc_bar {}
.jsxc-bar {}
.jsxc_window {
.jsxc-window {
bottom: 0;
box-shadow: none;
}
@@ -481,10 +470,10 @@ div {
}
}
.jsxc_fullscreen.jsxc_localvideo {
.jsxc-fullscreen.jsxc-localvideo {
border: 1px solid $white;
}
.jsxc_videoSuitable .jsxc_name {
.jsxc-videoSuitable .jsxc-name {
font-style: italic;
}
+104
Ver Arquivo
@@ -0,0 +1,104 @@
#jsxc-window-list {
@include presenceIndicator(".jsxc-window-bar .jsxc-avatar");
position: fixed;
bottom: 0;
right: 210px;
left: 0;
z-index: 50;
transition: right 0.5s;
.jsxc-roster-hidden & {
right: 10px;
}
@media (min-width: 768px) {
clip: rect(-10000px, 10000px, 30px, 30px);
}
> ul {
list-style: none;
padding: 0;
margin: 0;
position: absolute;
bottom: 0;
right: 0;
height: 44px;
overflow: visible;
white-space: nowrap;
transition: right 0.5s;
> li {
padding: 0;
margin: 0;
display: inline-block;
height: 44px;
width: 46px;
position: relative;
overflow: visible;
margin-right: 5px;
cursor: pointer;
white-space: normal;
&.jsxc-normal {
transition: width 0.2s;
width: 250px;
}
&.jsxc-minimized {
transition: width 0.2s;
width: 46px !important;
// overwrite resizeable width
@media (min-width: 768px) {
width: 200px !important;
}
.jsxc-emoticons {
display: none;
}
.jsxc-tools {
display: none;
}
}
}
}
}
#jsxc-window-list-handler {
position: fixed;
left: 0;
bottom: 0;
width: 30px;
height: 30px;
@media (max-width: 768px) {
display: none;
}
> {
div {
box-sizing: border-box;
width: 14px;
height: 100%;
background-color: $windowListSB_bg;
color: $windowListSB_color;
text-align: center;
line-height: 30px;
float: left;
cursor: pointer;
user-select: none;
&:hover {
background-color: $windowListSB_bg_hover;
}
}
.jsxc-disabled {
background-color: $windowListSB_bg_disabled !important;
color: $windowListSB_color_disabled;
cursor: default !important;
display: none;
}
}
}
+657
Ver Arquivo
@@ -0,0 +1,657 @@
.jsxc-window {
position: absolute;
bottom: 0;
top: auto;
left: 0;
right: 0;
height: auto;
background-color: $window_bg;
z-index: 80;
cursor: default;
border: 1px solid $window_border;
border-bottom: 0;
.jsxc-showOverlay & {
.jsxc-overlay {
display: block !important;
}
}
.jsxc-avatar {
margin-top: 1px;
}
.jsxc-message-area {
position: absolute;
top: 0;
right: 2px;
bottom: 44px;
left: 0;
overflow: auto;
padding: 3px;
z-index: 10;
&::-webkit-scrollbar {
width: 2px;
height: 2px;
}
&::-webkit-scrollbar-button {
width: 0;
height: 0;
}
&::-webkit-scrollbar-thumb {
background: #d1d1d1;
border: 0;
border-right: 3px solid transparent;
border-radius: 1px;
&:hover {
background: #c1c1c1;
}
&:active {
background: #b1b1b1;
}
}
&::-webkit-scrollbar-track {
background: transparent;
border: 0 none #fff;
border-radius: 50px;
&:hover {
background: transparent;
}
&:active {
background: transparent;
}
}
&::-webkit-scrollbar-corner {
background: transparent;
}
}
// .slimScrollDiv {
// margin: 0 0 6px;
// left: auto !important;
// top: auto !important;
// }
textarea {
&.jsxc-message-input {
width: 100%;
height: 44px;
margin: 0;
padding: 14px 40px 12px;
outline: none;
border-radius: 0;
box-sizing: border-box;
border: 0;
display: block;
resize: none;
transition: height 0.2s;
font-size: 13px;
position: absolute;
bottom: 0;
}
&::placeholder {
color: $window_placeholder;
opacity: 0.3;
}
}
.jsxc-tools {
float: right;
> .jsxc-disabled {
opacity: 0.3;
cursor: default !important;
}
> div {
width: 25px;
height: 40px;
display: block;
float: left;
color: $tools_color;
opacity: 0.4;
font-family: $font_sans;
line-height: 40px;
cursor: pointer;
text-align: center;
&.jsxc-menu {
opacity: 1;
}
}
}
.jsxc-close {
font-size: 20px;
&:hover {
color: $window_close_hover;
opacity: 1;
}
}
.jsxc-more {
background-image: url("../img/more_white.svg");
opacity: 0.4;
}
// .ui-resizable-w {
// left: 0;
// }
//
// .ui-resizable-nw {
// top: 0;
// left: 0;
// width: 15px;
// height: 15px;
// z-index: 95 !important;
// background-image: url("../img/resize_gray.svg");
// }
//
// .ui-resizable-n {
// position: absolute;
// top: 0;
// left: 0;
// right: 0;
// height: 15px;
// z-index: 100;
// }
}
.jsxc-window-bar {
background-color: $window_bar_bg;
cursor: pointer;
height: 44px;
line-height: 26px;
padding: 2px;
color: $window_bar_color;
width: 100%;
box-sizing: border-box;
position: relative;
transition: background-color 0.3s;
&:hover {
.jsxc-normal & {
color: $window_bar_color_hover;
}
}
.jsxc-tools {
&:hover {
.jsxc-normal & {
color: #000;
}
}
}
.jsxc-minimized & {
background-color: $window_min_bar_bg;
color: $window_min_bar_color;
}
.jsxc-highlight & {
background-color: orange;
}
}
.jsxc-window-fade {
position: relative;
height: 320px;
transition: height 0.2s;
overflow: hidden;
.jsxc-normal & {}
.jsxc-minimized & {
height: 0;
}
.jsxc-overlay {
display: none;
background-color: rgba(0, 0, 0, 0.5);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
overflow-y: scroll;
> div {
background-color: #fff;
margin: 30px 10px;
padding: 5px;
border-radius: 3px;
text-align: center;
position: relative;
.jsxc-close {
position: absolute;
top: 0;
right: 0;
height: 44px;
width: 44px;
&:after {
content: "×";
position: absolute;
top: 4px;
right: 4px;
font-size: 20px;
font-family: Arial, sans-serif;
cursor: pointer;
color: #000;
opacity: 0.4;
}
&:hover {
&:after {
opacity: 1;
}
}
@media (min-width: 768px) {
width: 30px;
height: 30px;
}
}
.jsxc-body {
margin-top: 20px;
}
p {
margin-bottom: 10px;
}
li {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
a:hover {
text-decoration: underline;
}
}
}
}
.jsxc-menu-emoticons {
height: 44px;
width: 44px;
position: absolute;
bottom: 0;
left: 0;
cursor: pointer;
z-index: 30;
&:after {
content: " ";
background-image: url("../img/smiley.svg");
background-position: center center;
background-repeat: no-repeat;
background-size: 30px 30px;
opacity: 0.3;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.jsxc-inner {
left: 5px;
}
ul {
width: 217px;
margin-bottom: 8px;
background-color: $emoticon_selection_bg;
border-radius: 3px;
z-index: 200;
list-style-type: none;
padding: 3px;
position: relative;
&:after {
content: " ";
position: absolute;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid $emoticon_selection_bg;
display: block;
width: 0;
z-index: 1;
left: 7px;
top: 100%;
}
}
li {
display: inline-block;
cursor: pointer;
border-radius: 3px;
width: 30px;
height: 30px;
&:hover {
background-color: $emoticon_selection_hover;
}
.jsxc-emoticon {
width: 100%;
height: 100%;
background-size: contain;
}
}
&:hover:after {
opacity: 0.5;
}
}
.jsxc-chatmessage {
margin: 3px;
padding: 4px;
word-wrap: break-word;
background-color: $chatmessage_bg;
position: relative;
outline: none;
clear: both;
&.jsxc-error {
opacity: 0.7;
&:before {
content: " ";
position: absolute;
top: 3px;
right: 3px;
width: 8px;
height: 8px;
background-color: yellow;
}
}
a {
color: $chatmessage_a;
text-decoration: underline;
display: inline-block;
max-width: 100%;
position: relative;
&[download]:before {
content: " ";
position: absolute;
top: 0;
right: 0;
bottom: 5px;
left: 0;
border-radius: 3px;
background-color: rgba(255, 255, 255, 0.7);
background-image: url("../img/download_icon_black.svg");
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
opacity: 0;
transition: opacity 0.5s;
}
&[download]:hover {
&:before {
opacity: 0.6;
}
}
}
img {
max-width: 100%;
}
.jsxc-avatar {
display: none;
}
.jsxc-attachment {
border-radius: 3px;
background-color: #fff;
padding: 3px 3px 3px 30px;
min-height: 30px;
margin-bottom: 5px;
background-position: 3px center;
background-size: 25px 25px;
background-repeat: no-repeat;
background-image: url("../img/filetypes/file.svg");
img {
border-radius: 3px;
}
&.jsxc-image {
line-height: 0;
padding: 0;
background-image: url("");
display: inline-block;
}
&.jsxc-application {
background-image: url("../img/filetypes/application.svg");
}
&.jsxc-application-pdf {
background-image: url("../img/filetypes/application-pdf.svg");
}
&.jsxc-audio {
background-image: url("../img/filetypes/audio.svg");
}
&.jsxc-video {
background-image: url("../img/filetypes/video.svg");
opacity: 1;
}
&.jsxc-text {
background-image: url("../img/filetypes/text.svg");
}
}
}
.jsxc-timestamp {
font-size: 8px;
color: $chatmessage_timestamp;
line-height: 8px;
overflow: hidden;
white-space: nowrap;
max-width: 100%;
text-overflow: ellipsis;
clear: both;
}
.jsxc-encrypted {
&.jsxc-received.jsxc-out .jsxc-timestamp {
margin-right: 1px;
}
.jsxc-timestamp:after {
content: " ";
display: inline-block;
width: 10px;
height: 8px;
margin-left: 2px;
background-image: url("../img/padlock_close_grey.svg");
background-size: contain;
background-repeat: no-repeat;
}
}
.jsxc-in {
float: left;
position: relative;
max-width: 76%;
margin-left: 10px;
border-radius: 3px;
background-color: $chatmessage_in_bg;
&:after {
content: " ";
position: absolute;
border-style: solid;
border-width: 5px 6px 5px 0;
border-color: transparent $chatmessage_in_bg;
display: block;
width: 0;
z-index: 1;
left: -6px;
bottom: 10px;
}
.jsxc-timestamp {
float: left;
}
}
.jsxc-out {
float: right;
position: relative;
max-width: 76%;
margin-right: 10px;
padding-right: 10px;
border-radius: 3px;
background-color: $chatmessage_out_bg;
&:after {
content: " ";
position: absolute;
border-style: solid;
border-width: 5px 0 5px 6px;
border-color: transparent $chatmessage_out_bg;
display: block;
width: 0;
z-index: 1;
right: -6px;
bottom: 10px;
}
&.jsxc-received {
&:before {
content: "";
position: absolute;
bottom: 2px;
right: 2px;
font-size: 12px;
line-height: 12px;
color: $chatmessage_received;
}
.jsxc-timestamp {
margin-right: 4px;
}
}
.jsxc-timestamp {
float: right;
}
}
.jsxc-sys {
width: auto;
max-width: none;
padding-right: 4px;
box-sizing: border-box;
margin-right: 3px;
border-radius: 3px;
background-color: transparent;
font-size: 0.8em;
font-style: italic;
.jsxc-emoticon {
width: 1.2em;
height: 1.2em;
vertical-align: middle;
}
&.jsxc-composing {
text-align: center;
font-size: 0.9em;
font-style: italic;
display: block;
opacity: 0;
overflow: hidden;
transition: opacity 0.6s;
&:before {
content: " ";
width: 1.5em;
height: 1em;
display: inline-block;
background-size: 80%;
background-repeat: no-repeat;
margin: 0 3px 0 0;
background-image: url("../img/composing.png");
}
&.jsxc-fadein {
opacity: 1;
}
}
}
.jsxc-menu-settings {
position: relative;
.jsxc-inner {
left: auto;
top: 100%;
right: -6px;
}
}
div.jsxc-transfer {
background-image: url("../img/padlock_open_black.svg");
background-repeat: no-repeat;
background-position: center center;
background-size: 14px 14px;
opacity: 0.3;
height: 44px;
width: 44px;
position: absolute;
bottom: 0;
right: 0;
cursor: pointer;
z-index: 20;
&:hover {
opacity: 1;
}
&.jsxc-disabled {
background-image: url("../img/padlock_open_disabled_black.svg");
cursor: default;
&:hover {
opacity: 0.3;
}
}
&.jsxc-fin {
opacity: 1;
background-image: url("../img/padlock_close_grey.svg");
}
&.jsxc-enc {
opacity: 1;
background-image: url("../img/padlock_close_orange.svg");
&.jsxc-trust {
background-image: url("../img/padlock_close_green.svg");
}
}
}
+61
Ver Arquivo
@@ -0,0 +1,61 @@
@import "../../lib/magnific-popup/src/css/main";
@import "../../lib/emojione/assets/css/emojione";
// BEGIN: bootstrap
@import "../../lib/bootstrap/assets/stylesheets/bootstrap/variables";
@import "../../lib/bootstrap/assets/stylesheets/bootstrap/mixins";
// Spec and IE10+
@keyframes progress-bar-stripes {
from {
background-position: 40px 0;
}
to {
background-position: 0 0;
}
}
#jsxc-dialog {
@import "../../lib/bootstrap/assets/stylesheets/bootstrap/progress-bars";
}
#jsxc-dialog, #jsxc-webrtc {
@import "../../lib/bootstrap/assets/stylesheets/bootstrap/utilities";
@import "../../lib/bootstrap/assets/stylesheets/bootstrap/code";
@import "../../lib/bootstrap/assets/stylesheets/bootstrap/grid";
@import "../../lib/bootstrap/assets/stylesheets/bootstrap/alerts";
@import "../../lib/bootstrap/assets/stylesheets/bootstrap/buttons";
@import "../../lib/bootstrap/assets/stylesheets/bootstrap/button-groups";
@import "../../lib/bootstrap/assets/stylesheets/bootstrap/forms";
.progress {
margin-bottom: 0;
.progress-bar {
width: 100%;
}
}
.mfp-close {
font-size: 23px;
}
}
.mfp-bg {
z-index: 9000;
}
.mfp-wrap {
z-index: 9010;
}
.mfp-content {
text-align: center;
}
// END: bootstrap
#cboxWrapper {
outline: none;
}
+334
Ver Arquivo
@@ -0,0 +1,334 @@
import Storage from './Storage'
import {IConnection} from './connection/ConnectionInterface'
import * as Connector from './connection/xmpp/connector'
import XMPPConnection from './connection/xmpp/Connection'
import StorageConnection from './connection/storage/Connection'
import JID from './JID'
import Contact from './Contact'
import ContactData from './ContactData'
import Roster from './ui/Roster'
import ChatWindow from './ui/ChatWindow'
import ChatWindowList from './ui/ChatWindowList'
import SortedPersistentMap from './SortedPersistentMap'
import PersistentMap from './PersistentMap'
import Log from './util/Log'
import {Presence} from './connection/AbstractConnection'
import Client from './Client'
import {Notice, NoticeData, TYPE as NOTICETYPE} from './Notice'
interface IConnectionParameters {
url:string,
jid: string,
sid?:string,
rid?:string,
timestamp?:number,
inactivity?:number
};
export default class Account {
private storage:Storage;
private uid:string;
private connection:IConnection;
private connectionArguments;
private connectionParameters:IConnectionParameters;
private contacts = {};
private windows:SortedPersistentMap;
private notices:SortedPersistentMap;
private contact:Contact;
constructor(boshUrl: string, jid: string, sid: string, rid:string);
constructor(boshUrl: string, jid: string, password: string);
constructor(uid:string);
constructor() {
if (arguments.length === 1) {
this.uid = arguments[0];
} else if (arguments.length === 3 || arguments.length === 4) {
this.uid = (new JID(arguments[1])).bare;
this.connectionArguments = arguments;
}
this.connection = new StorageConnection(this);
this.contact = new Contact(this, new ContactData({
jid: new JID(this.uid),
name: this.uid
}));
Roster.get().setRosterAvatar(this.contact);
this.restoreContacts();
this.initNotices();
this.initWindows();
this.getStorage().registerHook('contact:', (contactData) => {
let contact = new Contact(this, contactData.jid);
if (typeof this.contacts[contact.getId()] === 'undefined') { console.log('add', contactData.jid)
this.contacts[contact.getId()] = contact;
Roster.get().add(contact);
}
});
}
public connect() {
let self = this;
if (!this.connectionArguments) {
this.reloadConnectionData();
}
if (self.connectionParameters && self.connectionParameters.inactivity && (new Date()).getTime() - self.connectionParameters.timestamp > self.connectionParameters.inactivity) {
Log.warn('Credentials expired')
this.closeAllChatWindows();
return Promise.reject('Credentials expired');
}
return Connector.login.apply(this, this.connectionArguments).then(this.successfulConnected);
}
public getContact(jid:JID):Contact {
return this.contacts[jid.bare];
}
public addContact(data:ContactData):Contact {
let contact = new Contact(this, data);
contact.save();
this.contacts[contact.getId()] = contact;
this.save();
return contact;
}
public removeContact(contact:Contact) {
let id = contact.getId();
if (this.contacts[id]) {
delete this.contacts[id];
Roster.get().remove(contact);
//@REVIEW contact.getChatWindow would be nice
let chatWindow = this.windows.get(id);
if (chatWindow) {
this.closeChatWindow(chatWindow);
}
}
}
public removeAllContacts() {
for(let id in this.contacts) {
let contact = this.contacts[id];
delete this.contacts[id];
Roster.get().remove(contact);
}
}
public openChatWindow(contact:Contact) {
let chatWindow = new ChatWindow(this, contact);
chatWindow = ChatWindowList.get().add(chatWindow);
this.windows.push(chatWindow);
this.save();
return chatWindow;
}
public closeChatWindow(chatWindow:ChatWindow) {
// let id = chatWindow.getContact().getId();
console.log('chatWindow', chatWindow)
ChatWindowList.get().remove(chatWindow);
this.windows.remove(chatWindow);
this.save();
}
public closeAllChatWindows() {
this.windows.empty((id, chatWindow) => {
ChatWindowList.get().remove(chatWindow);
});
}
public addNotice(noticeData:NoticeData) {
let notice = new Notice(this.getStorage(), noticeData);
if (this.notices.get(notice.getId())) {
return;
}
//Roster.get().addNotice(this, notice);
this.notices.push(notice);
}
public removeNotice(notice:Notice) { console.log('removeNotice', notice);
//Roster.get().removeNotice(this, notice);
this.notices.remove(notice);
}
public getStorage() {
if(!this.storage) {
this.storage = new Storage(this.uid);
}
return this.storage;
}
public getConnection():IConnection {
return this.connection;
}
public getUid() {
return this.uid;
}
public getJID():JID {
let storedAccountData = this.getStorage().getItem('account') || {};
let jidString = (storedAccountData.connectionParameters) ? storedAccountData.connectionParameters.jid : this.getUid();
//@REVIEW maybe promise?
return new JID(jidString);
}
public remove() {
this.removeAllContacts();
this.closeAllChatWindows();
Client.removeAccount(this);
}
private successfulConnected = (data) => {
let connection = data.connection;
let status = data.status;
this.connectionParameters = $.extend(this.connectionParameters, {
url: connection.service,
jid: connection.jid,
sid: connection._proto.sid,
rid: connection._proto.rid,
timestamp: (new Date()).getTime()
});
if (connection._proto.inactivity) {
this.connectionParameters.inactivity = connection._proto.inactivity * 1000;
}
this.save();
connection.connect_callback = (status) => {
if (status === Strophe.Status.DISCONNECTED) {
this.connectionDisconnected();
}
}
connection.nextValidRid = (rid) => {
this.connectionParameters.timestamp = (new Date()).getTime();
this.connectionParameters.rid = rid;
this.save();
};
this.connection = new XMPPConnection(this, connection);
if (status === Strophe.Status.CONNECTED) {
Roster.get().setPresence(Presence.online);
Roster.get().refreshOwnPresenceIndicator();
this.connection.getRoster().then(() => {
this.connection.sendPresence();
});
} else {
this.connection.sendPresence();
}
}
private connectionDisconnected() {
console.log('disconnected');
this.remove();
}
private save() {
this.getStorage().setItem('account', {
connectionParameters: this.connectionParameters,
contacts: Object.keys(this.contacts),
// windows: Object.keys(this.windows)
});
}
private reloadConnectionData() {
let storedAccountData = this.getStorage().getItem('account') || {};
console.log('storedAccountData', storedAccountData)
this.connectionParameters = storedAccountData.connectionParameters;
let p = this.connectionParameters;
this.connectionArguments = [p.url, (new JID(p.jid)).full, p.sid, p.rid];
}
private restoreContacts() {
let storedAccountData = this.getStorage().getItem('account');
storedAccountData.contacts.forEach((id) => {
this.contacts[id] = new Contact(this, id);
Roster.get().add(this.contacts[id]);
});
}
private initWindows() {
this.windows = new SortedPersistentMap(this.getStorage(), 'windows');
this.windows.setRemoveHook((id, chatWindow) => {
console.log('remove hook', id, chatWindow);
if (chatWindow) {
ChatWindowList.get().remove(chatWindow);
}
});
this.windows.setPushHook((id) => {
let chatWindow = new ChatWindow(this, this.contacts[id]);
this.windows[id] = chatWindow;
ChatWindowList.get().add(chatWindow);
return chatWindow;
});
this.windows.init();
}
private initNotices() {
this.notices = new SortedPersistentMap(this.getStorage(), 'notices');
this.notices.setRemoveHook((id) => {
Roster.get().removeNotice(this, id);
});
this.notices.setPushHook((id) => {
let notice = new Notice(this.getStorage(), id);
Roster.get().addNotice(this, notice);
return notice;
});
this.notices.init();
}
}
+112
Ver Arquivo
@@ -0,0 +1,112 @@
import Options from './Options';
import Log from './util/Log';
export default class Attachment {
private mimeType:string;
private data:any;
private thumbnailData:any;
private size:number;
private persistent:boolean;
private name:string;
constructor(name:string, mimeType:string, data:any);
constructor(id:string);
constructor() {
// @TODO
}
public save():boolean {
if (this.isImage() && this.data && !this.thumbnailData) {
this.generateThumbnail();
}
if (this.size > Options.get('maxStorableSize')) {
Log.debug('Attachment to large to store');
this.persistent = false;
return false;
//@TODO delete data and store thumbnailData
}
//@TODO save to storage
return true;
}
public getSize():number {
return this.size;
}
public getMimeType():string {
return this.mimeType;
}
public getThumbnailData() {
return this.thumbnailData;
}
public getName() {
return this.name;
}
public isPersistent():boolean {
return this.persistent;
}
public isImage():boolean {
return /^image\//i.test(this.mimeType);
}
public hasThumbnailData():boolean {
return !!this.thumbnailData;
}
public hasData():boolean {
return !!this.data;
}
public clearData() {
this.data = null;
}
private generateThumbnail():void {
if(typeof Image === 'undefined') {
return;
}
var sHeight, sWidth, sx, sy;
var dHeight = 100,
dWidth = 100;
var canvas = <HTMLCanvasElement> $("<canvas>").get(0);
canvas.width = dWidth;
canvas.height = dHeight;
var ctx = canvas.getContext("2d");
var img = new Image();
img.src = this.data;
if (img.height > img.width) {
sHeight = img.width;
sWidth = img.width;
sx = 0;
sy = (img.height - img.width) / 2;
} else {
sHeight = img.height;
sWidth = img.height;
sx = (img.width - img.height) / 2;
sy = 0;
}
ctx.drawImage(img, sx, sy, sWidth, sHeight, 0, 0, dWidth, dHeight);
this.thumbnailData = canvas.toDataURL();
}
}
+20
Ver Arquivo
@@ -0,0 +1,20 @@
export let NOTIFICATION_DEFAULT = 'default';
export let NOTIFICATION_GRANTED = 'granted';
export let NOTIFICATION_DENIED = 'denied';
export let STATUS = ['offline', 'dnd', 'xa', 'away', 'chat', 'online'];
export let SOUNDS = {
MSG: 'incomingMessage.wav',
CALL: 'Rotary-Phone6.mp3',
NOTICE: 'Ping1.mp3'
};
export let REGEX = {
JID: new RegExp('\\b[^"&\'\\/:<>@\\s]+@[\\w-_.]+\\b', 'ig'),
URL: new RegExp(/(https?:\/\/|www\.)[^\s<>'"]+/gi)
};
export let NS = {
CARBONS: 'urn:xmpp:carbons:2',
FORWARD: 'urn:xmpp:forward:0'
};
export let HIDDEN = 'hidden';
export let SHOWN = 'shown';
+116
Ver Arquivo
@@ -0,0 +1,116 @@
import Account from './Account'
import Message from './Message'
import {PluginInterface} from './PluginInterface'
import Storage from './Storage';
import * as UI from './ui/web'
import JID from './JID'
import Roster from './ui/Roster'
import ChatWindowList from './ui/ChatWindowList'
import RoleAllocator from './RoleAllocator'
export default class Client implements ClientInterface {
private static storage;
private static accounts = {};
public static init() {
let roleAllocator = RoleAllocator.get();
let accountIds = Client.getStorage().getItem('accounts') || [];
accountIds.forEach(function(id) {
Client.accounts[id] = new Account(id);
roleAllocator.waitUntilMaster().then(function(){
return Client.accounts[id].connect();
}).then(function(){
}).catch(function(msg){
Client.accounts[id].remove();
console.warn(msg)
});
});
}
public static addConnectionPlugin(plugin:PluginInterface) {
}
public static addPreSendMessageHook(hook:(Message, Builder)=>void, position?:number) {
}
public static hasFocus() {
}
public static isExtraSmallDevice():boolean {
return $(window).width() < 500;
}
public static isDebugMode():boolean {
return Client.getStorage().getItem('debug') === true;
}
public static getStorage() {
if (!Client.storage) {
Client.storage = new Storage();
}
return Client.storage;
}
public static getAccout(jid:JID):Account;
public static getAccout(uid?:string):Account;
public static getAccout() {
let uid;
if (arguments[0] instanceof JID) {
uid = arguments[0].bare;
} else if (arguments[0]) {
uid = arguments[0];
} else {
uid = Object.keys(Client.accounts)[0];
}
return Client.accounts[uid];
}
public static createAccount(boshUrl: string, jid: string, sid: string, rid:string);
public static createAccount(boshUrl: string, jid: string, password: string);
public static createAccount() {
let account;
if (arguments.length === 4) {
account = new Account(arguments[0], arguments[1], arguments[2], arguments[3]);
} else if (arguments.length === 3) {
account = new Account(arguments[0], arguments[1], arguments[2]);
} else {
return Promise.reject(null);
}
return account.connect().then(function(){
Client.addAccount(account);
});
}
public static removeAccount(account:Account) {
delete Client.accounts[account.getUid()];
Client.save();
if (Object.keys(Client.accounts).length === 0) {
Roster.get().setNoConnection();
}
}
private static addAccount(account:Account) {
Client.accounts[account.getUid()] = account;
Client.save()
}
private static save() {
Client.getStorage().setItem('accounts', Object.keys(this.accounts));
}
}
+26
Ver Arquivo
@@ -0,0 +1,26 @@
import {JIDInterface} from './JIDInterface'
import {PluginInterface} from './PluginInterface'
export interface ClientInterface {
init();
addConnectionPlugin(plugin:PluginInterface);
addPreSendMessageHook(hook:(Message, Builder)=>void, position?:number);
hasFocus();
isExtraSmallDevice():boolean;
isDebugMode():boolean;
getStorage();
getAccout(jid:JIDInterface):Account;
getAccout(uid?:string):Account;
createAccount(boshUrl: string, jid: string, sid: string, rid:string);
createAccount(boshUrl: string, jid: string, password: string);
removeAccount(account:Account);
}
+228
Ver Arquivo
@@ -0,0 +1,228 @@
import Storage from './Storage'
import JID from './JID'
import Message from './Message'
import Notification from './Notification'
import Translation from './util/Translation'
import Account from './Account'
import ContactData from './ContactData'
import PersistentMap from './PersistentMap'
import IdentifiableInterface from './IdentifiableInterface'
import Log from './util/Log'
import {Presence} from './connection/AbstractConnection'
export default class Contact implements IdentifiableInterface {
private storage: Storage;
private readonly account:Account;
// @REVIEW Data to own object/type?
private data:PersistentMap;
private jid:JID;
constructor(account:Account, data: ContactData);
constructor(account:Account, id:string);
constructor() {
this.account = arguments[0];
this.storage = this.account.getStorage();
if (typeof arguments[1] === 'string') {
let id = arguments[1]; console.log('id', id)
this.data = new PersistentMap(this.storage, 'contact', id);
this.jid = new JID(this.data.get('jid'));
return;
}
let data = arguments[1] || {};
if (!data.jid) {
throw 'Jid missing';
} else if (typeof data.jid === 'string') {
this.jid = new JID(data.jid);
} else {
this.jid = data.jid;
data.jid = this.jid.full;
}
this.data = new PersistentMap(this.storage, 'contact', this.jid.bare);
data.rnd = Math.random() // force storage event
this.data.set(data);
}
public save() {
// if (this.storage.getItem('contact', this.getId())) {
// this.storage.updateItem('contact', this.getId(), this.data);
//
// return 'updated';
// }
//
// this.storage.setItem('contact', this.getId(), this.data);
//
// return 'created';
}
public openWindow = () => {
return this.account.openChatWindow(this);
}
public addResource(resource:string) {
let resources = this.data.get('resources') || [];
if (resource && resources.indexOf(resource) < 0) {
resources.push(resource);
this.data.set('resources', resources);
}
}
public removeResource(resource:string) {
let resources = this.data.get('resources') || [];
resources = $.grep(resources, function(r) {
return resource !== r;
});
this.data.set('resources', resources);
}
public setResource = (resource:string) => {
//this.addResource(resource);
console.log('setResource', this.jid.bare + '/' + resource)
this.jid = new JID(this.jid.bare + '/' + resource);
this.data.set('jid', this.jid.full);
}
public setPresence(resource:string, presence:Presence) {
Log.debug('set presence for ' + this.jid.bare + ' / ' + resource, presence);
let resources = this.data.get('resources') || {};
if (presence === Presence.offline) {
delete resources[resource];
} else if (resource) {
resources[resource] = presence;
}
if (this.getType() === 'groupchat') {
// group chat doesn't have a presence
return;
}
presence = this.getHighestPresence();
console.log('highest presence', presence);
if (this.data.get('presence') === Presence.offline && presence !== Presence.offline) {
// buddy has come online
// @TODO
// Notification.notify({
// title: this.getName(),
// message: Translation.t('has_come_online'),
// source: this.getId()
// });
}
this.data.set('presence', presence);
}
public sendMessage(message:Message) {
// message.bid = this.getId();
}
public getId():string {
return this.jid.bare;
}
public getJid():JID {
return this.jid;
}
public getFingerprint() {
return this.data.get('fingerprint');
}
public getMsgState() {
return this.data.get('msgstate');
}
public getPresence() {
return this.data.get('presence');
}
public getType() {
return this.data.get('type');
}
public getNumberOfUnreadMessages():number {
}
public getName():string {
return this.data.get('name') || this.jid.bare;
}
public getAvatar():Promise<{}> {
}
public getSubscription() {
return this.data.get('subscription');
}
public getCapabilitiesByRessource():Promise<{}> {
// @TODO
return Promise.resolve({});
}
public getVcard():Promise<{}> {
return this.account.getConnection().loadVcard(this.getJid());
}
public isEncrypted() {
}
public getStatus():string {
return this.data.get('status');
}
public setStatus(status:string) { console.trace(this.getId() + ', setStatus: ' + status)
return this.data.set('status', status);
}
public setTrust(trust:boolean) {
this.data.set('trust', trust);
}
public setName(name:string) {
let oldName = this.getName();
this.data.set('name', name);
if (oldName !== name) {
this.account.getConnection().setDisplayName(this.jid, name);
}
}
public setSubscription(subscription:string) {
this.data.set('subscription', subscription);
}
public registerHook(property:string, func:(newValue:any, oldValue:any)=>void) {
this.data.registerHook(property, func);
}
private getHighestPresence() {
let maxPresence = Presence.offline;
let resources = this.data.get('resources');
for (let resource in resources) {
if(resources[resource] < maxPresence) {
maxPresence = resources[resource];
}
}
return maxPresence;
}
}
+26
Ver Arquivo
@@ -0,0 +1,26 @@
//@TODO duplicate of AbstractConnection
enum Presence {
online,
chat,
away,
xa,
dnd,
offline
}
export default class ContactData {
public jid;
public name;
public presence:Presence = Presence.offline;
public status:string = '';
public subscription = 'none';
public msgstate = 0;
public trust:boolean = false;
public fingerprint:string = null;
public resources = {};
public type = 'chat'
constructor(data:any) {
$.extend(this, data);
}
}
+55
Ver Arquivo
@@ -0,0 +1,55 @@
import {MessageInterface} from './MessageInterface'
import {JIDInterface} from './JIDInterface'
import {Presence} from './connection/AbstractConnection'
export interface ContactInterface {
openWindow();
addResource(resource:string);
removeResource(resource:string);
setResource(resource:string);
setPresence(resource:string, presence:Presence);
sendMessage(message:MessageInterface);
getId():string;
getJid():JIDInterface;
getFingerprint();
getMsgState();
getPresence();
getType();
getNumberOfUnreadMessages():number;
getName():string;
getAvatar():Promise<{}>;
getSubscription();
getCapabilitiesByRessource():Promise<{}>;
getVcard():Promise<{}>;
isEncrypted();
getStatus():string;
setStatus(status:string);
setTrust(trust:boolean);
setName(name:string);
setSubscription(subscription:string);
registerHook(property:string, func:(newValue:any, oldValue:any)=>void);
}
Ver Arquivo
+127
Ver Arquivo
@@ -0,0 +1,127 @@
import Options from './Options'
const EMOTICONS = [
['O:-) O:)', 'innocent'],
['>:-( >:( &gt;:-( &gt;:(', 'angry'],
[':-) :)', 'slight_smile'],
[':-D :D', 'grin'],
[':-( :(', 'disappointed'],
[';-) ;)', 'wink'],
[':-P :P', 'stuck_out_tongue'],
['=-O', 'astonished'],
[':kiss: :-*', 'kissing_heart'],
['8-) :cool:', 'sunglasses'],
[':-X :X', 'zipper_mouth'],
[':yes:', 'thumbsup'],
[':no:', 'thumbsdown'],
[':beer:', 'beer'],
[':coffee:', 'coffee'],
[':devil:', 'smiling_imp'],
[':kiss: :kissing:', 'kissing'],
['@->-- @-&gt;--', 'rose'],
[':music:', 'musical_note'],
[':love:', 'heart_eyes'],
[':heart:', 'heart'],
[':brokenheart:', 'broken_heart'],
[':zzz:', 'zzz'],
[':wait:', 'hand_splayed']
]
import * as emojione from '../lib/emojione/lib/js/emojione.js';
const EMOTICON_LIST = {
'core': {
':klaus:': ['klaus'],
':jabber:': ['jabber'],
':xmpp:': ['xmpp'],
':jsxc:': ['jsxc'],
':owncloud:': ['owncloud'],
':nextcloud:': ['nextcloud']
},
'emojione': emojione.emojioneList
}
export default class Emoticons {
private static initialised = false;
private static shortRegex = new RegExp(emojione.regShortNames.source + '|(' + Object.keys(EMOTICON_LIST.core).join('|') + ')', 'gi');
public static getDefaultEmoticonList() {
let list = [];
EMOTICONS.forEach(emoticon => {
list.push(emoticon[0].split(' ')[0]);
});
return list;
}
public static toImage(text:string):string {
Emoticons.init();
text = Emoticons.standardToImage(text);
text = Emoticons.shortnameToImage(text);
return text;
}
private static init() {
if (Emoticons.initialised) {
return;
}
$.each(EMOTICONS, function(i, val) {
// escape characters
var reg = val[0].replace(/(\/|\||\*|\.|\+|\?|\^|\$|\(|\)|\[|\]|\{|\})/g, '\\$1');
reg = '(' + reg.split(' ').join('|') + ')';
EMOTICONS[i][2] = new RegExp(reg, 'g');
});
Emoticons.initialised = true;
}
private static standardToImage(text:string):string {
// replace emoticons from XEP-0038 and pidgin with shortnames
$.each(EMOTICONS, function(i, val) {
text = text.replace(val[2], ':' + val[1] + ':');
});
return text;
}
private static shortnameToImage(text:string):string {
text = text.replace(this.shortRegex, Emoticons.replaceShortnameWithImage);
var wrapper = $('<div>' + text + '</div>');
if (wrapper.find('.jsxc_emoticon').length === 1 && wrapper.text().replace(/ /, '').length === 0 && wrapper.find('*').length === 1) {
wrapper.find('.jsxc_emoticon').addClass('jsxc_large');
text = wrapper.html();
}
return text;
}
private static replaceShortnameWithImage = (shortname) => {
if (typeof shortname === 'undefined' || shortname === '' || (!(shortname in EMOTICON_LIST.emojione) && !(shortname in EMOTICON_LIST.core))) {
return shortname;
}
var src, filename;
if (EMOTICON_LIST.core[shortname]) {
filename = EMOTICON_LIST.core[shortname][EMOTICON_LIST.core[shortname].length - 1].replace(/^:([^:]+):$/, '$1');
src = Options.get('root') + '/img/emotions/' + filename + '.svg';
} else if (EMOTICON_LIST.emojione[shortname]) {
filename = EMOTICON_LIST.emojione[shortname].fname;
src = Options.get('root') + '/lib/emojione/assets/svg/' + filename + '.svg';
}
var div = $('<div>');
div.addClass('jsxc-emoticon');
div.css('background-image', 'url(' + src + ')');
div.attr('title', shortname);
return div.prop('outerHTML');
}
}
+6
Ver Arquivo
@@ -0,0 +1,6 @@
interface Identifiable {
getId():string
}
export default Identifiable;
+65
Ver Arquivo
@@ -0,0 +1,65 @@
import {JIDInterface} from './JIDInterface'
export default class JID implements JIDInterface {
public readonly full:string;
public readonly bare:string;
public readonly node:string;
public readonly domain:string;
public readonly resource:string;
constructor(full:string) {
let matches = /([^@]+)@([^/]+)(?:\/(.+))?/.exec(full);
this.node = this.unescapeNode(matches[1].toLowerCase());
this.domain = matches[2].toLowerCase();
this.resource = matches[3];
this.bare = this.node + '@' + this.domain;
this.full = this.bare + ((this.resource) ? '/' + this.resource : '');
}
public toString():string {
return this.full;
}
public toEscapedString():string {
let bare = this.escapeNode(this.node) + '@' + this.domain;
return bare + ((this.resource) ? '/' + this.resource : '');
}
public isBare():boolean {
return this.full === this.bare;
}
private escapeNode(node:string) {
return node.replace(/^\s+|\s+$/g, '')
.replace(/\\/g, "\\5c")
.replace(/ /g, "\\20")
.replace(/\"/g, "\\22")
.replace(/\&/g, "\\26")
.replace(/\'/g, "\\27")
.replace(/\//g, "\\2f")
.replace(/:/g, "\\3a")
.replace(/</g, "\\3c")
.replace(/>/g, "\\3e")
.replace(/@/g, "\\40");
}
private unescapeNode(node:string) {
return node.replace(/\\20/g, " ")
.replace(/\\22/g, '"')
.replace(/\\26/g, "&")
.replace(/\\27/g, "'")
.replace(/\\2f/g, "/")
.replace(/\\3a/g, ":")
.replace(/\\3c/g, "<")
.replace(/\\3e/g, ">")
.replace(/\\40/g, "@")
.replace(/\\5c/g, "\\");
}
}
+16
Ver Arquivo
@@ -0,0 +1,16 @@
export interface JIDInterface {
readonly full:string;
readonly bare:string;
readonly node:string;
readonly domain:string;
readonly resource:string;
toString():string;
isBare():boolean;
}
+244
Ver Arquivo
@@ -0,0 +1,244 @@
import Storage from './Storage';
import Log from './util/Log';
import Options from './Options';
import Attachment from './Attachment';
import StorageSingleton from './StorageSingleton';
import JID from './JID'
import * as CONST from './CONST'
import Emoticons from './Emoticons'
import Translation from './util/Translation'
import Identifiable from './IdentifiableInterface'
import Client from './Client'
import Utils from './util/Utils'
import {MessageInterface, DIRECTION, MSGTYPE} from './MessageInterface'
const MSGPOSTFIX = ':msg';
const ATREGEX = new RegExp('(xmpp:)?(' + CONST.REGEX.JID.source + ')(\\?[^\\s]+\\b)?', 'i');
interface MessagePayload {
peer:JID,
direction:DIRECTION,
plaintextMessage?:string,
htmlMessage?:string,
errorMessage?:string,
attachment?:Attachment,
received?:boolean,
encrypted?:boolean,
forwarded?:boolean,
stamp?:number,
type?:MSGTYPE,
}
export default class Message implements Identifiable, MessageInterface {
private uid:string;
private payload:MessagePayload = {
received: false,
encrypted: null,
forwarded: false,
stamp: new Date().getTime(),
type: MSGTYPE.CHAT
} as any;
static readonly DIRECTION = DIRECTION;
static readonly MSGTYPE = MSGTYPE;
private storage:Storage;
constructor(uid:string);
constructor(data:MessagePayload);
constructor() {
this.storage = Client.getStorage();
if (typeof arguments[0] === 'string' && arguments[0].length > 0 && arguments.length === 1) {
this.uid = arguments[0];
this.load(this.uid);
} else if (typeof arguments[0] === 'object' && arguments[0] !== null) { console.log('arg', arguments[0])
$.extend(this.payload, arguments[0]);
}
if (!this.uid) {
this.uid = new Date().getTime() + MSGPOSTFIX;
}
}
public getId() {
return this.uid;
}
public save() {
let attachment = this.getAttachment();
if (attachment) {
if (this.getDirection() === DIRECTION.OUT) {
// save storage
attachment.clearData();
}
let saved = attachment.save();
if (!saved && this.getDirection() === DIRECTION.IN) {
//@TODO inform user
}
}
let payloadCopy = $.extend({}, this.payload); //Object.assign
if (payloadCopy.attachment) {
payloadCopy.attachment = payloadCopy.attachment.getId();
}
this.storage.setItem('msg', this.uid, {
payload: payloadCopy
});
return this;
}
public delete() {
var data = this.storage.getItem('msg', this.uid);
if (data) {
this.storage.removeItem('msg', this.uid);
}
}
public getCssId() {
return this.uid.replace(/:/g, '-');
}
public getDOM() {
return $('#' + this.getCssId());
}
public getStamp() {
return this.payload.stamp;
}
public getDirection():DIRECTION {
return this.payload.direction;
}
public getDirectionString():string {
return DIRECTION[this.payload.direction].toLowerCase();
}
public getAttachment():Attachment {
return this.payload.attachment;
}
public getPeer():JID {
return this.payload.peer;
}
public getType():MSGTYPE {
return this.payload.type;
}
public getTypeString():string {
return MSGTYPE[this.payload.type].toLowerCase();
}
public getHtmlMessage():string {
return this.payload.htmlMessage;
}
public getPlaintextMessage():string {
return this.payload.plaintextMessage;
}
public received() {
this.payload.received = true;
this.save();
this.getDOM().addClass('jsxc_received');
}
public isReceived():boolean {
return this.payload.received;
}
public isForwarded():boolean {
return this.payload.forwarded;
}
public isEncrypted():boolean {
return this.payload.encrypted;
}
public hasAttachment():boolean {
return !!this.payload.attachment;
}
public setUnread() {
}
public getProcessedBody():string {
let body = this.payload.plaintextMessage;
body = this.convertUrlToLink(body);
body = this.convertEmailToLink(body);
body = Emoticons.toImage(body);
body = this.replaceLineBreaks(body);
// hide unprocessed otr messages
if (body.match(/^\?OTR([:,|?]|[?v0-9x]+)/)) {
body = '<i title="' + body + '">' + Translation.t('Unreadable_OTR_message') + '</i>';
}
return body;
}
public getErrorMessage():string {
return this.payload.errorMessage;
}
private load(uid:string):void {
var data = this.storage.getItem('msg', uid);
window._storage = this.storage;
if (!data) {
Log.debug('Could not load message with uid ' + uid);
throw new Error('Could not load message with uid ' + uid)
}
$.extend(this.payload, data.payload);
if (data.attachment) {
this.payload.attachment = new Attachment(data.attachment);
}
}
private replaceLineBreaks(text) {
return text.replace(/(\r\n|\r|\n)/g, '<br />');
}
private convertUrlToLink(text) {
return text.replace(CONST.REGEX.URL, function(url) {
let href = (url.match(/^https?:\/\//i)) ? url : 'http://' + url;
return '<a href="' + href + '" target="_blank">' + url + '</a>';
});
}
private convertEmailToLink(text) {
return text.replace(ATREGEX, function(undefined, protocol, jid, action) {
if (protocol === 'xmpp:') {
if (typeof action === 'string') {
jid += action;
}
return '<a href="xmpp:' + jid + '">xmpp:' + jid + '</a>';
}
return '<a href="mailto:' + jid + '" target="_blank">mailto:' + jid + '</a>';
});
}
}
+55
Ver Arquivo
@@ -0,0 +1,55 @@
import {JIDInterface} from './JIDInterface'
export enum DIRECTION {
IN, OUT, SYS
};
export enum MSGTYPE {
CHAT, GROUPCHAT
};
export interface MessageInterface {
getId();
save();
delete();
getCssId();
getDOM();
getStamp();
getDirection():DIRECTION;
getDirectionString():string;
getAttachment():Attachment;
getPeer():JIDInterface;
getType():MSGTYPE;
getTypeString():string;
getHtmlMessage():string;
getPlaintextMessage():string;
received();
isReceived():boolean;
isForwarded():boolean;
isEncrypted():boolean;
hasAttachment():boolean;
setUnread();
getProcessedBody():string;
getErrorMessage():string;
}
+52
Ver Arquivo
@@ -0,0 +1,52 @@
import Storable from './StorableAbstract';
import Identifiable from './IdentifiableInterface'
import Storage from './Storage'
const SEP = ':';
export default class ModelManager <Element extends Storable> {
private id:string;
private elementIds;
constructor(private owner:Identifiable, private ElementClass:any, private storage:Storage) { //@REVIEW any -> Element?
this.id = owner.getId() + SEP + ElementClass.constructor.name;
this.elementIds = this.storage.getItem(this.id);
}
public get(id:string):Element {
let data = this.storage.getItem(this.id + SEP + id);
return new this.ElementClass(data);
}
public getAll():Element[] {
let elements:Element[] = [];
for(let elementId in this.elementIds) {
elements.push(this.get(elementId));
}
return elements;
}
public add(element:Element) {
this.elementIds.push(element.getId());
this.save();
}
public remove(element:Element) {
this.elementIds = $.grep(this.elementIds, function(e) {
return e !== element.getId();
})
this.save();
}
private save() {
this.storage.setItem(this.id, this.elementIds);
}
}
+68
Ver Arquivo
@@ -0,0 +1,68 @@
import IdentifiableInterface from './IdentifiableInterface'
import Storage from './Storage'
import ContactDialog from './ui/dialogs/contact'
export const enum TYPE {
normal, announcement, contact
}
export const enum FUNCTION {
contactRequest
}
let functions = {};
functions[FUNCTION.contactRequest] = ContactDialog;
export interface NoticeData {
title:string;
description:string;
fnName: FUNCTION;
fnParams?:Array<string>;
type?:TYPE;
}
export class Notice implements IdentifiableInterface {
private storage:Storage;
private data:NoticeData;
constructor(storage:Storage, data:NoticeData);
constructor(storage:Storage, id:string);
constructor() {
this.storage = arguments[0];
if (arguments.length === 2 && typeof arguments[1] === 'string') {
this.data = this.storage.getItem(arguments[1]);
} else {
this.data = arguments[1];
this.data.fnParams = this.data.fnParams || [];
this.data.type = this.data.type || TYPE.normal;
this.storage.setItem(this.getId(), this.data);
}
}
public getId():string {
return this.data.fnName + '|' + this.data.fnParams.toString();
}
public getTitle():string {
return this.data.title;
}
public getDescription():string {
return this.data.description;
}
public getFnParams():Array<string> {
return this.data.fnParams;
}
public getType():TYPE {
return this.data.type;
}
public callFunction() {
return functions[this.data.fnName].apply(this, this.data.fnParams);
}
}
+178
Ver Arquivo
@@ -0,0 +1,178 @@
import Options from './Options'
import Contact from './Contact'
import Translation from './util/Translation'
import Client from './Client'
import * as CONST from './CONST'
interface NotificationSettings {
title:string,
message:string,
duration?:number,
force?:boolean,
soundFile?:string,
loop?:boolean,
source?:string,
icon?:string
};
export default class Notification {
private static inited = false;
private static popupTimeout;
private static popupDelay = 1000;
private static audioObject;
public static init() {
if(Notification.inited) {
return;
}
$(document).on('postmessagein.jsxc', function(event, bid, msg) {
msg = (msg && msg.match(/^\?OTR/)) ? $.t('Encrypted_message') : msg;
var data = jsxc.storage.getUserItem('buddy', bid);
Notification.notify({
title: Translation.t('New_message_from'),
message: msg,
soundFile: CONST.SOUNDS.MSG,
source: bid
});
});
$(document).on('callincoming.jingle', function() {
Notification.playSound(CONST.SOUNDS.CALL, true, true);
});
$(document).on('accept.call.jsxc reject.call.jsxc', function() {
Notification.stopSound();
});
if (!Notice.has('gui.showRequestNotification')) {
Notice.add({
msg: Translation.t('Notifications') + '?',
description: Translation.t('Should_we_notify_you_')
}, 'gui.showRequestNotification');
}
}
public static muteSound(external?) {
$('#jsxc-menu .jsxc-muteNotification').text(Translation.t('Unmute'));
if (external !== true) {
Options.set('muteNotification', true);
}
}
public static unmuteSound(external?) {
$('#jsxc-menu .jsxc-muteNotification').text(Translation.t('Mute'));
if (external !== true) {
Options.set('muteNotification', false);
}
}
public static notify(settings:NotificationSettings) {
if (!Options.get('notification') || !Notification.hasPermission()) {
return; // notifications disabled
}
if (Client.hasFocus() && !settings.force) {
return; // Tab is visible
}
settings.icon = settings.icon || Options.get('root') + '/img/XMPP_logo.png';
if (typeof settings.source === 'string') {
let contact = new Contact(settings.source);
let avatar = contact.getAvatar();
if (typeof avatar === 'string' && avatar !== '0') {
settings.icon = avatar;
}
}
settings.duration = settings.duration || Options.get('notification').duration;
settings.title = Translation.t(settings.title);
settings.message = Translation.t(settings.message);
Notification.popupTimeout = setTimeout(function() {
Notification.showPopup(settings);
}, Notification.popupDelay);
}
private static showPopup(settings:NotificationSettings) {
if (typeof settings.soundFile === 'string') {
Notification.playSound(settings.soundFile, settings.loop, settings.force);
}
var popup = new window.Notification(settings.title, {
body: settings.message,
icon: settings.icon
});
if (settings.duration > 0) {
setTimeout(function() {
popup.close();
}, settings.duration);
}
}
private static hasSupport() {
return !!window.Notification;
}
private static requestPermission() {
window.Notification.requestPermission(function(status) {
if (window.Notification.permission !== status) {
window.Notification.permission = status;
}
if (Notification.hasPermission()) {
$(document).trigger('notificationready.jsxc');
} else {
$(document).trigger('notificationfailure.jsxc');
}
});
}
private static hasPermission() {
return window.Notification.permission === CONST.NOTIFICATION_GRANTED;
}
private static playSound(soundFile:string, loop?:boolean, force?:boolean) {
if (!jsxc.master) {
// only master plays sound
return;
}
if (Options.get('muteNotification') || jsxc.storage.getUserItem('presence') === 'dnd') {
// sound mute or own presence is dnd
return;
}
if (Client.hasFocus() && !force) {
// tab is visible
return;
}
// stop current audio file
Notification.stopSound();
var audio = new Audio(Options.get('root') + '/sound/' + soundFile);
audio.loop = loop || false;
audio.play();
Notification.audioObject = audio;
}
private static stopSound() {
var audio = Notification.audioObject;
if (typeof audio !== 'undefined' && audio !== null) {
audio.pause();
Notification.audioObject = null;
}
}
}
+64 -53
Ver Arquivo
@@ -1,30 +1,39 @@
/**
* Set some options for the chat.
*
* @namespace jsxc.options
*/
jsxc.options = {
export default class Options {
public static get(key) {
if (jsxc && jsxc.bid) {
var local = jsxc.storage.getUserItem('options') || {};
return (typeof local[key] !== 'undefined') ? local[key] : Options[key];
}
return (typeof Options[key] !== 'undefined') ? Options[key] : {};
};
public static set(key, value) {
jsxc.storage.updateItem('options', key, value, true);
};
/** name of container application (e.g. owncloud or SOGo) */
app_name: 'web applications',
private static app_name = 'web applications';
/** Timeout for the keepalive signal */
timeout: 3000,
private static timeout = 3000;
/** Timeout for the keepalive signal if the master is busy */
busyTimeout: 15000,
private static busyTimeout = 15000;
/** OTR options */
otr: {
private static otr = {
enable: true,
ERROR_START_AKE: false,
debug: false,
SEND_WHITESPACE_TAG: false,
WHITESPACE_START_AKE: true
},
};
/** xmpp options */
xmpp: {
private static xmpp = {
/** BOSH url */
url: null,
@@ -48,16 +57,16 @@ jsxc.options = {
/** @deprecated since v2.1.0. Use now loginForm.enable. */
onlogin: null
},
};
/** default xmpp priorities */
priority: {
private static priority = {
online: 0,
chat: 0,
away: 0,
xa: 0,
dnd: 0
},
};
/**
* This function is called if a login form was found, but before any
@@ -66,10 +75,10 @@ jsxc.options = {
* @memberOf jsxc.options
* @function
*/
formFound: null,
private static formFound = null;
/** If all 3 properties are set and enable is true, the login form is used */
loginForm: {
private static loginForm = {
/** False, disables login through login form */
enable: true,
@@ -128,45 +137,45 @@ jsxc.options = {
* roster state will be used.
*/
startMinimized: false
},
};
/** jquery object from logout element */
logoutElement: null,
private static logoutElement = null;
/** How many messages should be logged? */
numberOfMsg: 10,
private static numberOfMsg = 10;
/** Default language */
defaultLang: 'en',
private static defaultLang = 'en';
/** auto language detection */
autoLang: true,
private static autoLang = true;
/** Place for roster */
rosterAppend: 'body',
private static rosterAppend = 'body';
/** Should we use the HTML5 notification API? */
notification: true,
private static notification = true;
/** duration for notification */
popupDuration: 6000,
private static popupDuration = 6000;
/** Absolute path root of JSXC installation */
root: '',
private static root = '/jsxc4.0/';
/**
* This function decides wether the roster will be displayed or not if no
* connection is found.
*/
displayRosterMinimized: function() {
private static displayRosterMinimized = function() {
return false;
},
};
/** Set to true if you want to hide offline buddies. */
hideOffline: false,
private static hideOffline = false;
/** Mute notification sound? */
muteNotification: false,
private static muteNotification = false;
/**
* If no avatar is found, this function is called.
@@ -174,9 +183,9 @@ jsxc.options = {
* @param jid Jid of that user.
* @this {jQuery} Elements to update with probable .jsxc_avatar elements
*/
defaultAvatar: function(jid) {
private static defaultAvatar = function(jid) {
jsxc.gui.avatarPlaceholder($(this).find('.jsxc_avatar'), jid);
},
};
/**
* This callback processes all settings.
@@ -193,7 +202,7 @@ jsxc.options = {
* @param password {string} password
* @param cb {loadSettingsCallback} Callback that handles the result
*/
loadSettings: null,
private static loadSettings = null;
/**
* Call this function to save user settings permanent.
@@ -202,14 +211,14 @@ jsxc.options = {
* @param data Holds all data as key/value
* @param cb Called with true on success, false otherwise
*/
saveSettinsPermanent: function(data, cb) {
private static saveSettinsPermanent = function(data, cb) {
cb(true);
},
};
carbons: {
private static carbons = {
/** Enable carbon copies? */
enable: true
},
};
/**
* Processes user list.
@@ -226,10 +235,10 @@ jsxc.options = {
* @param {string} search Search token (start with)
* @param {getUsers-cb} cb Called with list of users
*/
getUsers: null,
private static getUsers = null;
/** Options for info in favicon */
favicon: {
private static favicon = {
enable: true,
/** Favicon info background color */
@@ -237,13 +246,13 @@ jsxc.options = {
/** Favicon info text color */
textColor: '#fff'
},
};
/** @deprecated since v2.1.0. Use now RTCPeerConfig.url. */
turnCredentialsPath: null,
private static turnCredentialsPath = null;
/** RTCPeerConfiguration used for audio/video calls. */
RTCPeerConfig: {
private static RTCPeerConfig = {
/** Time-to-live for config from url */
ttl: 3600,
@@ -257,12 +266,12 @@ jsxc.options = {
iceServers: [{
urls: 'stun:stun.stunprotocol.org'
}]
},
};
/** Link to an online user manual */
onlineHelp: 'http://www.jsxc.org/manual.html',
private static onlineHelp = 'http://www.jsxc.org/manual.html';
viewport: {
private static viewport = {
getSize: function() {
var w = $(window).width() - $('#jsxc_windowListSB').width();
var h = $(window).height();
@@ -276,23 +285,23 @@ jsxc.options = {
height: h
};
}
},
};
/** Maximal storage size for attachments received via data channels (webrtc). */
maxStorableSize: 1000000,
private static maxStorableSize = 1000000;
/** Options for file transfer. */
fileTransfer: {
private static fileTransfer = {
httpUpload: {
enable: true
},
// @TODO add option to enable/disable data channels
},
};
/** Default option for chat state notifications */
chatState: {
private static chatState = {
enable: true
},
};
/**
* Download urls to screen media extensions.
@@ -300,8 +309,10 @@ jsxc.options = {
* @type {Object}
* @see example extensions {@link https://github.com/otalk/getScreenMedia}
*/
screenMediaExtension: {
private static screenMediaExtension = {
firefox: '',
chrome: ''
}
};
private static storage;
};

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais