Compare commits
208 Commits
08-05-2018
...
dark-theme
Author | SHA1 | Date | |
---|---|---|---|
a7337fa918 | |||
da047a976a | |||
379826f16b | |||
5dc64492cb | |||
5ac5101ced | |||
f91ffba2a4 | |||
affe9a96f5 | |||
44fa0bea24 | |||
e77b509202 | |||
06b43732a9 | |||
ee2689ad84 | |||
8eadb03d59 | |||
6e0b3a4345 | |||
c633ce13b5 | |||
40593e00ed | |||
e214573e4e | |||
0825aba022 | |||
7a65263873 | |||
97f476e416 | |||
3dce138811 | |||
28edb3122f | |||
2cd9338417 | |||
0af31052b4 | |||
81ba811622 | |||
4b7008b5ba | |||
02744d5c72 | |||
52c963cf1b | |||
52d1328f93 | |||
50b40ac5b0 | |||
e1c3b0c002 | |||
f859abcb2f | |||
6e08208fed | |||
391c74df62 | |||
5f2deebfb5 | |||
6fa2123d57 | |||
536570abf1 | |||
ad67f6d852 | |||
ac6539a82c | |||
1e1021fd49 | |||
499aefbc1d | |||
c973b33ac8 | |||
3397ddbf44 | |||
607d2fafca | |||
ec7abaaf14 | |||
a389d731c2 | |||
4d7a99aeea | |||
04b80782dc | |||
837bc35a6b | |||
c98683e573 | |||
f6eea9ebf8 | |||
7e99e8b14b | |||
95b4c5fbc7 | |||
a50cca62d3 | |||
f122da1306 | |||
0692a689f1 | |||
fc8abc6d56 | |||
547daf4741 | |||
476f1b24a7 | |||
693b1fa26c | |||
655432a500 | |||
bd888f0f47 | |||
ede515f7a2 | |||
fa24c2d090 | |||
1522248793 | |||
cc1e4dd22a | |||
61a20e8708 | |||
a5815272c8 | |||
f66aba031c | |||
059fcc72b6 | |||
acb4e1b384 | |||
74e06a2b89 | |||
2032017b0c | |||
500633862e | |||
57306d6872 | |||
31bbc2326c | |||
5c0cdced85 | |||
07af7c961d | |||
ddd54e05e5 | |||
1fb1e62fb6 | |||
80630dae58 | |||
85c117ff81 | |||
a62d2a495e | |||
51c248e463 | |||
665cbb8374 | |||
5cfee77bb2 | |||
a8e686d59b | |||
6111e527e0 | |||
1b9ccfc95b | |||
59c917f599 | |||
b67f3b055f | |||
1d88b8ea69 | |||
d541506820 | |||
c9d0a597f5 | |||
e805dda4fb | |||
0be49b0d35 | |||
0c20b97b2f | |||
d32c1428cf | |||
f90dc5d9ae | |||
89df9f0315 | |||
561a3e9342 | |||
66392491b5 | |||
a100d4a403 | |||
9866298f19 | |||
3bda514879 | |||
7db41a9183 | |||
dfce597139 | |||
24357aeb05 | |||
a438eb81f0 | |||
1d92a5bf1c | |||
eb69734a38 | |||
6239d43f05 | |||
4c3985fc24 | |||
218e9b6fbe | |||
30696174f2 | |||
a3ddd525d0 | |||
2b8a7f08cb | |||
e28b99f40c | |||
b527b3a22d | |||
0b5e50aade | |||
dd53a39c4b | |||
f4e1b47d9d | |||
28cb1e22e7 | |||
7ff7bceca3 | |||
074b724d68 | |||
1ae92eeac8 | |||
30fd40ad72 | |||
972232b370 | |||
2e0b130ac5 | |||
2c07e76684 | |||
9325cdd68b | |||
19797b8731 | |||
4ea1761c72 | |||
e0d5e50357 | |||
f5638c3196 | |||
fa1c1596d5 | |||
bde2b5dde6 | |||
91f8edd2de | |||
9a7c3245c4 | |||
79da14e0bc | |||
683a8eb0e6 | |||
b0c4971838 | |||
d01b9f4803 | |||
f4d019046d | |||
f41ac3b107 | |||
8777832600 | |||
8458c6190d | |||
725871dab1 | |||
d687e9962e | |||
7abe97c1c2 | |||
cfa5be5612 | |||
b679b7e651 | |||
2fc2b0d641 | |||
c2b8177792 | |||
b9cc47f05d | |||
ec13b6902b | |||
19576cebed | |||
ebd2fcf4f5 | |||
73dfc842af | |||
1f636b7a5f | |||
4a20815619 | |||
bf00a52430 | |||
bca2e6449e | |||
46912f47c7 | |||
7a473d1aa8 | |||
92c7c80fbc | |||
701d070efd | |||
4ec6213877 | |||
e06a658422 | |||
d086f9dfab | |||
8f668c1bfa | |||
88308778d7 | |||
7db7ecf69a | |||
f447f30c6c | |||
e9b6df8536 | |||
e32a7c67e1 | |||
e376c789a6 | |||
1d9ae0dadd | |||
1a922704ed | |||
7a3387b550 | |||
5e29916f97 | |||
d0ae8d0620 | |||
4ef2e7f219 | |||
b412214976 | |||
1e299b6d5e | |||
5c5110a7cf | |||
84df7adc89 | |||
7ccfec5845 | |||
b69811105f | |||
925e0b11e8 | |||
9126a08d2f | |||
4383efa32c | |||
688a9de2b1 | |||
2c260c7174 | |||
42c934b723 | |||
cb2a7a5b04 | |||
28097368e1 | |||
877d9b40f5 | |||
aefc20198c | |||
4ac1b15520 | |||
b457786ae9 | |||
d6413887c2 | |||
e55614b4c8 | |||
53edcd8ffc | |||
99f86060a4 | |||
0c68b8dd5d | |||
11d5bdf752 | |||
27401c9070 | |||
beafe2580a |
13
.travis.yml
Normal file
@ -0,0 +1,13 @@
|
||||
sudo: required
|
||||
|
||||
language: php
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
#Target PHP versions
|
||||
php:
|
||||
- 7.2
|
||||
|
||||
script:
|
||||
- docker run -t -v $(pwd):/data pierre42100/docker-comunicwebappscratch /data/builder build offline
|
2
LICENSE
@ -1,5 +1,5 @@
|
||||
MIT License
|
||||
Copyright (c) <year> <copyright holders>
|
||||
Copyright (c) 2017-2018 Pierre HUBERT
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
@ -21,3 +21,8 @@ ComunicWeb would not exists without the following technologies developped by the
|
||||
- jquery.hotkeys
|
||||
- bootstrap-wysiwyg (https://github.com/steveathon/bootstrap-wysiwyg/)
|
||||
- wdt-emoji-bundle (http://ned.im/wdt-emoji-bundle)
|
||||
- PNGLib (http://www.xarg.org/2010/03/generate-client-side-png-files-using-javascript/) (BSD Licence)
|
||||
- Identicon (http://github.com/stewartlord/identicon.js) (BSD Licence)
|
||||
- FileSaver.js (http://eligrey.com) (by Eli Grey) (MIT Licence)
|
||||
- JSZip (https://github.com/Stuk/jszip.git) (MIT Licence)
|
||||
- JSZip Utils (https://github.com/Stuk/jszip-utils.git) (MIT Licence)
|
247
assets/3rdparty/FileSaver.js
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
/*! FileSaver.js
|
||||
* A saveAs() FileSaver implementation.
|
||||
* 2014-01-24
|
||||
*
|
||||
* By Eli Grey, http://eligrey.com
|
||||
* License: X11/MIT
|
||||
* See LICENSE.md
|
||||
*/
|
||||
|
||||
/*global self */
|
||||
/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
|
||||
|
||||
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
|
||||
|
||||
var saveAs = saveAs
|
||||
// IE 10+ (native saveAs)
|
||||
|| (typeof navigator !== "undefined" &&
|
||||
navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator))
|
||||
// Everyone else
|
||||
|| (function(view) {
|
||||
"use strict";
|
||||
// IE <10 is explicitly unsupported
|
||||
if (typeof navigator !== "undefined" &&
|
||||
/MSIE [1-9]\./.test(navigator.userAgent)) {
|
||||
return;
|
||||
}
|
||||
var
|
||||
doc = view.document
|
||||
// only get URL when necessary in case BlobBuilder.js hasn't overridden it yet
|
||||
, get_URL = function() {
|
||||
return view.URL || view.webkitURL || view;
|
||||
}
|
||||
, URL = view.URL || view.webkitURL || view
|
||||
, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
|
||||
, can_use_save_link = !view.externalHost && "download" in save_link
|
||||
, click = function(node) {
|
||||
var event = doc.createEvent("MouseEvents");
|
||||
event.initMouseEvent(
|
||||
"click", true, false, view, 0, 0, 0, 0, 0
|
||||
, false, false, false, false, 0, null
|
||||
);
|
||||
node.dispatchEvent(event);
|
||||
}
|
||||
, webkit_req_fs = view.webkitRequestFileSystem
|
||||
, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
|
||||
, throw_outside = function(ex) {
|
||||
(view.setImmediate || view.setTimeout)(function() {
|
||||
throw ex;
|
||||
}, 0);
|
||||
}
|
||||
, force_saveable_type = "application/octet-stream"
|
||||
, fs_min_size = 0
|
||||
, deletion_queue = []
|
||||
, process_deletion_queue = function() {
|
||||
var i = deletion_queue.length;
|
||||
while (i--) {
|
||||
var file = deletion_queue[i];
|
||||
if (typeof file === "string") { // file is an object URL
|
||||
URL.revokeObjectURL(file);
|
||||
} else { // file is a File
|
||||
file.remove();
|
||||
}
|
||||
}
|
||||
deletion_queue.length = 0; // clear queue
|
||||
}
|
||||
, dispatch = function(filesaver, event_types, event) {
|
||||
event_types = [].concat(event_types);
|
||||
var i = event_types.length;
|
||||
while (i--) {
|
||||
var listener = filesaver["on" + event_types[i]];
|
||||
if (typeof listener === "function") {
|
||||
try {
|
||||
listener.call(filesaver, event || filesaver);
|
||||
} catch (ex) {
|
||||
throw_outside(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
, FileSaver = function(blob, name) {
|
||||
// First try a.download, then web filesystem, then object URLs
|
||||
var
|
||||
filesaver = this
|
||||
, type = blob.type
|
||||
, blob_changed = false
|
||||
, object_url
|
||||
, target_view
|
||||
, get_object_url = function() {
|
||||
var object_url = get_URL().createObjectURL(blob);
|
||||
deletion_queue.push(object_url);
|
||||
return object_url;
|
||||
}
|
||||
, dispatch_all = function() {
|
||||
dispatch(filesaver, "writestart progress write writeend".split(" "));
|
||||
}
|
||||
// on any filesys errors revert to saving with object URLs
|
||||
, fs_error = function() {
|
||||
// don't create more object URLs than needed
|
||||
if (blob_changed || !object_url) {
|
||||
object_url = get_object_url(blob);
|
||||
}
|
||||
if (target_view) {
|
||||
target_view.location.href = object_url;
|
||||
} else {
|
||||
window.open(object_url, "_blank");
|
||||
}
|
||||
filesaver.readyState = filesaver.DONE;
|
||||
dispatch_all();
|
||||
}
|
||||
, abortable = function(func) {
|
||||
return function() {
|
||||
if (filesaver.readyState !== filesaver.DONE) {
|
||||
return func.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
}
|
||||
, create_if_not_found = {create: true, exclusive: false}
|
||||
, slice
|
||||
;
|
||||
filesaver.readyState = filesaver.INIT;
|
||||
if (!name) {
|
||||
name = "download";
|
||||
}
|
||||
if (can_use_save_link) {
|
||||
object_url = get_object_url(blob);
|
||||
// FF for Android has a nasty garbage collection mechanism
|
||||
// that turns all objects that are not pure javascript into 'deadObject'
|
||||
// this means `doc` and `save_link` are unusable and need to be recreated
|
||||
// `view` is usable though:
|
||||
doc = view.document;
|
||||
save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a");
|
||||
save_link.href = object_url;
|
||||
save_link.download = name;
|
||||
var event = doc.createEvent("MouseEvents");
|
||||
event.initMouseEvent(
|
||||
"click", true, false, view, 0, 0, 0, 0, 0
|
||||
, false, false, false, false, 0, null
|
||||
);
|
||||
save_link.dispatchEvent(event);
|
||||
filesaver.readyState = filesaver.DONE;
|
||||
dispatch_all();
|
||||
return;
|
||||
}
|
||||
// Object and web filesystem URLs have a problem saving in Google Chrome when
|
||||
// viewed in a tab, so I force save with application/octet-stream
|
||||
// http://code.google.com/p/chromium/issues/detail?id=91158
|
||||
if (view.chrome && type && type !== force_saveable_type) {
|
||||
slice = blob.slice || blob.webkitSlice;
|
||||
blob = slice.call(blob, 0, blob.size, force_saveable_type);
|
||||
blob_changed = true;
|
||||
}
|
||||
// Since I can't be sure that the guessed media type will trigger a download
|
||||
// in WebKit, I append .download to the filename.
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=65440
|
||||
if (webkit_req_fs && name !== "download") {
|
||||
name += ".download";
|
||||
}
|
||||
if (type === force_saveable_type || webkit_req_fs) {
|
||||
target_view = view;
|
||||
}
|
||||
if (!req_fs) {
|
||||
fs_error();
|
||||
return;
|
||||
}
|
||||
fs_min_size += blob.size;
|
||||
req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
|
||||
fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
|
||||
var save = function() {
|
||||
dir.getFile(name, create_if_not_found, abortable(function(file) {
|
||||
file.createWriter(abortable(function(writer) {
|
||||
writer.onwriteend = function(event) {
|
||||
target_view.location.href = file.toURL();
|
||||
deletion_queue.push(file);
|
||||
filesaver.readyState = filesaver.DONE;
|
||||
dispatch(filesaver, "writeend", event);
|
||||
};
|
||||
writer.onerror = function() {
|
||||
var error = writer.error;
|
||||
if (error.code !== error.ABORT_ERR) {
|
||||
fs_error();
|
||||
}
|
||||
};
|
||||
"writestart progress write abort".split(" ").forEach(function(event) {
|
||||
writer["on" + event] = filesaver["on" + event];
|
||||
});
|
||||
writer.write(blob);
|
||||
filesaver.abort = function() {
|
||||
writer.abort();
|
||||
filesaver.readyState = filesaver.DONE;
|
||||
};
|
||||
filesaver.readyState = filesaver.WRITING;
|
||||
}), fs_error);
|
||||
}), fs_error);
|
||||
};
|
||||
dir.getFile(name, {create: false}, abortable(function(file) {
|
||||
// delete file if it already exists
|
||||
file.remove();
|
||||
save();
|
||||
}), abortable(function(ex) {
|
||||
if (ex.code === ex.NOT_FOUND_ERR) {
|
||||
save();
|
||||
} else {
|
||||
fs_error();
|
||||
}
|
||||
}));
|
||||
}), fs_error);
|
||||
}), fs_error);
|
||||
}
|
||||
, FS_proto = FileSaver.prototype
|
||||
, saveAs = function(blob, name) {
|
||||
return new FileSaver(blob, name);
|
||||
}
|
||||
;
|
||||
FS_proto.abort = function() {
|
||||
var filesaver = this;
|
||||
filesaver.readyState = filesaver.DONE;
|
||||
dispatch(filesaver, "abort");
|
||||
};
|
||||
FS_proto.readyState = FS_proto.INIT = 0;
|
||||
FS_proto.WRITING = 1;
|
||||
FS_proto.DONE = 2;
|
||||
|
||||
FS_proto.error =
|
||||
FS_proto.onwritestart =
|
||||
FS_proto.onprogress =
|
||||
FS_proto.onwrite =
|
||||
FS_proto.onabort =
|
||||
FS_proto.onerror =
|
||||
FS_proto.onwriteend =
|
||||
null;
|
||||
|
||||
view.addEventListener("unload", process_deletion_queue, false);
|
||||
saveAs.unload = function() {
|
||||
process_deletion_queue();
|
||||
view.removeEventListener("unload", process_deletion_queue, false);
|
||||
};
|
||||
return saveAs;
|
||||
}(
|
||||
typeof self !== "undefined" && self
|
||||
|| typeof window !== "undefined" && window
|
||||
|| this.content
|
||||
));
|
||||
// `self` is undefined in Firefox for Android content script context
|
||||
// while `this` is nsIContentFrameMessageManager
|
||||
// with an attribute `content` that corresponds to the window
|
||||
|
||||
if (typeof module !== "undefined") module.exports = saveAs;
|
@ -9,7 +9,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(flat.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/flat.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -49,7 +49,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat,
|
||||
.iradio_flat {
|
||||
background-image: url(flat@2x.png);
|
||||
background-image: url(icheck-flat-imgs/flat@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
@ -65,7 +65,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(red.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/red.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -105,7 +105,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-red,
|
||||
.iradio_flat-red {
|
||||
background-image: url(red@2x.png);
|
||||
background-image: url(icheck-flat-imgs/red@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
@ -121,7 +121,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(green.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/green.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -161,7 +161,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-green,
|
||||
.iradio_flat-green {
|
||||
background-image: url(green@2x.png);
|
||||
background-image: url(icheck-flat-imgs/green@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
@ -177,7 +177,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(blue.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/blue.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -217,7 +217,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-blue,
|
||||
.iradio_flat-blue {
|
||||
background-image: url(blue@2x.png);
|
||||
background-image: url(icheck-flat-imgs/blue@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
@ -233,7 +233,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(aero.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/aero.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -273,7 +273,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-aero,
|
||||
.iradio_flat-aero {
|
||||
background-image: url(aero@2x.png);
|
||||
background-image: url(icheck-flat-imgs/aero@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
@ -289,7 +289,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(grey.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/grey.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -329,7 +329,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-grey,
|
||||
.iradio_flat-grey {
|
||||
background-image: url(grey@2x.png);
|
||||
background-image: url(icheck-flat-imgs/grey@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
@ -345,7 +345,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(orange.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/orange.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -385,7 +385,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-orange,
|
||||
.iradio_flat-orange {
|
||||
background-image: url(orange@2x.png);
|
||||
background-image: url(icheck-flat-imgs/orange@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
@ -401,7 +401,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(yellow.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/yellow.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -441,7 +441,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-yellow,
|
||||
.iradio_flat-yellow {
|
||||
background-image: url(yellow@2x.png);
|
||||
background-image: url(icheck-flat-imgs/yellow@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
@ -457,7 +457,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(pink.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/pink.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -497,7 +497,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-pink,
|
||||
.iradio_flat-pink {
|
||||
background-image: url(pink@2x.png);
|
||||
background-image: url(icheck-flat-imgs/pink@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
@ -513,7 +513,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(purple.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/purple.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -553,7 +553,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-purple,
|
||||
.iradio_flat-purple {
|
||||
background-image: url(purple@2x.png);
|
||||
background-image: url(icheck-flat-imgs/purple@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(aero.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/aero.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -49,7 +49,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-aero,
|
||||
.iradio_flat-aero {
|
||||
background-image: url(aero@2x.png);
|
||||
background-image: url(icheck-flat-imgs/aero@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(blue.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/blue.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -49,7 +49,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-blue,
|
||||
.iradio_flat-blue {
|
||||
background-image: url(blue@2x.png);
|
||||
background-image: url(icheck-flat-imgs/blue@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(flat.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/flat.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -49,7 +49,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat,
|
||||
.iradio_flat {
|
||||
background-image: url(flat@2x.png);
|
||||
background-image: url(icheck-flat-imgs/flat@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(green.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/green.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -49,7 +49,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-green,
|
||||
.iradio_flat-green {
|
||||
background-image: url(green@2x.png);
|
||||
background-image: url(icheck-flat-imgs/green@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(grey.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/grey.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -49,7 +49,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-grey,
|
||||
.iradio_flat-grey {
|
||||
background-image: url(grey@2x.png);
|
||||
background-image: url(icheck-flat-imgs/grey@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
@ -9,7 +9,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(orange.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/orange.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -49,7 +49,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-orange,
|
||||
.iradio_flat-orange {
|
||||
background-image: url(orange@2x.png);
|
||||
background-image: url(icheck-flat-imgs/orange@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(pink.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/pink.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -49,7 +49,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-pink,
|
||||
.iradio_flat-pink {
|
||||
background-image: url(pink@2x.png);
|
||||
background-image: url(icheck-flat-imgs/pink@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(purple.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/purple.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -49,7 +49,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-purple,
|
||||
.iradio_flat-purple {
|
||||
background-image: url(purple@2x.png);
|
||||
background-image: url(icheck-flat-imgs/purple@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(red.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/red.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -49,7 +49,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-red,
|
||||
.iradio_flat-red {
|
||||
background-image: url(red@2x.png);
|
||||
background-image: url(icheck-flat-imgs/red@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
padding: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: url(yellow.png) no-repeat;
|
||||
background: url(icheck-flat-imgs/yellow.png) no-repeat;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -49,7 +49,7 @@
|
||||
only screen and (min-device-pixel-ratio: 1.5) {
|
||||
.icheckbox_flat-yellow,
|
||||
.iradio_flat-yellow {
|
||||
background-image: url(yellow@2x.png);
|
||||
background-image: url(icheck-flat-imgs/yellow@2x.png);
|
||||
-webkit-background-size: 176px 22px;
|
||||
background-size: 176px 22px;
|
||||
}
|
||||
|
5
assets/3rdparty/bootstrap-wysiwyg.js
vendored
@ -59,6 +59,11 @@
|
||||
}.bind( this ) );
|
||||
|
||||
$( window ).bind( "touchend", function( e ) {
|
||||
|
||||
//COMUNIC FIX
|
||||
if(!this.getCurrentRange)
|
||||
return;
|
||||
|
||||
var isInside = ( editor.is( e.target ) || editor.has( e.target ).length > 0 ),
|
||||
currentRange = this.getCurrentRange(),
|
||||
clear = currentRange && ( currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset );
|
||||
|
8
assets/3rdparty/identicon.js/LICENSE
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
Copyright (c) 2018, Stewart Lord
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
73
assets/3rdparty/identicon.js/README.md
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
identicon.js
|
||||
============
|
||||
|
||||

|
||||
|
||||
[](https://cdnjs.com/libraries/identicon.js)
|
||||
|
||||
GitHub-style identicons as PNGs or SVGs in JS.
|
||||
|
||||
This little library will produce the same shape and (nearly) the same color as GitHub when given the same hash value. Supports PNG and SVG output formats. Note that GitHub uses an internal database identifier for the hash, so you can't simply md5 the username and get the same result. The creative visual design is borrowed from [Jason Long](http://twitter.com/jasonlong) of Git and GitHub fame.
|
||||
|
||||
Demo
|
||||
----
|
||||
[View Demo](https://rawgithub.com/stewartlord/identicon.js/master/demo.html)
|
||||
|
||||
Installation
|
||||
-----
|
||||
```
|
||||
npm install identicon.js --save
|
||||
```
|
||||
[](https://npmjs.org/package/identicon.js)
|
||||
|
||||
Options
|
||||
----
|
||||
* **hash** - A hexadecimal string of 15+ characters that will be used to generate the image.
|
||||
* **options** - [Optional] An options object used to customize the generated image.
|
||||
* **size** - The size in pixels of the height and width of the generated (square) image. Defaults to 64 pixels.
|
||||
* **margin** - The decimal fraction of the size to use for margin. For example, use 0.2 for a 20% margin. Defaults to 0.08 for an 8% margin.
|
||||
* **foreground** - The foreground color is automatically derived from the hash value. Use this option to override that behavior and provide a rgba value array instead (e.g. [255,0,0,255] for red).
|
||||
* **background** - The background color expressed as an rgba value array to use for the image background. For example, use [255,0,0,255] for red. Defaults to an opaque light gray [240,240,240,255].
|
||||
* **saturation** - The saturation of the derived foreground color as a value from 0-1. Defaults to 0.7.
|
||||
* **brightness** - The brightness of the derived foreground color as a value from 0-1. Defaults to 0.5.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
##### Simple
|
||||
Generate the Identicon by supplying a hash string and size.
|
||||
```js
|
||||
|
||||
// create a base64 encoded PNG
|
||||
var data = new Identicon('d3b07384d113edec49eaa6238ad5ff00', 420).toString();
|
||||
|
||||
// write to a data URI
|
||||
document.write('<img width=420 height=420 src="data:image/png;base64,' + data + '">');
|
||||
```
|
||||
|
||||
##### Advanced
|
||||
To customize additional properties, generate the Identicon by supplying a hexadecimal string and an options object.
|
||||
```js
|
||||
// set up options
|
||||
var hash = "c157a79031e1c40f85931829bc5fc552"; // 15+ hex chars
|
||||
var options = {
|
||||
foreground: [0, 0, 0, 255], // rgba black
|
||||
background: [255, 255, 255, 255], // rgba white
|
||||
margin: 0.2, // 20% margin
|
||||
size: 420, // 420px square
|
||||
format: 'svg' // use SVG instead of PNG
|
||||
};
|
||||
|
||||
// create a base64 encoded SVG
|
||||
var data = new Identicon(hash, options).toString();
|
||||
|
||||
// write to a data URI
|
||||
document.write('<img width=420 height=420 src="data:image/svg+xml;base64,' + data + '">');
|
||||
```
|
||||
|
||||
|
||||
[PNG output requires PNGLib](http://www.xarg.org/download/pnglib.js)
|
||||
|
||||
Copyright 2018, [Stewart Lord](https://github.com/stewartlord)
|
||||
Released under the [BSD license](http://www.opensource.org/licenses/bsd-license.php)
|
205
assets/3rdparty/identicon.js/identicon.js
vendored
Normal file
@ -0,0 +1,205 @@
|
||||
/**
|
||||
* Identicon.js 2.3.2
|
||||
* http://github.com/stewartlord/identicon.js
|
||||
*
|
||||
* PNGLib required for PNG output
|
||||
* http://www.xarg.org/download/pnglib.js
|
||||
*
|
||||
* Copyright 2018, Stewart Lord
|
||||
* Released under the BSD license
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var PNGlib;
|
||||
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||||
PNGlib = require('./pnglib');
|
||||
} else {
|
||||
PNGlib = window.PNGlib;
|
||||
}
|
||||
|
||||
var Identicon = function(hash, options){
|
||||
if (typeof(hash) !== 'string' || hash.length < 15) {
|
||||
throw 'A hash of at least 15 characters is required.';
|
||||
}
|
||||
|
||||
this.defaults = {
|
||||
background: [240, 240, 240, 255],
|
||||
margin: 0.08,
|
||||
size: 64,
|
||||
saturation: 0.7,
|
||||
brightness: 0.5,
|
||||
format: 'png'
|
||||
};
|
||||
|
||||
this.options = typeof(options) === 'object' ? options : this.defaults;
|
||||
|
||||
// backward compatibility with old constructor (hash, size, margin)
|
||||
if (typeof(arguments[1]) === 'number') { this.options.size = arguments[1]; }
|
||||
if (arguments[2]) { this.options.margin = arguments[2]; }
|
||||
|
||||
this.hash = hash
|
||||
this.background = this.options.background || this.defaults.background;
|
||||
this.size = this.options.size || this.defaults.size;
|
||||
this.format = this.options.format || this.defaults.format;
|
||||
this.margin = this.options.margin !== undefined ? this.options.margin : this.defaults.margin;
|
||||
|
||||
// foreground defaults to last 7 chars as hue at 70% saturation, 50% brightness
|
||||
var hue = parseInt(this.hash.substr(-7), 16) / 0xfffffff;
|
||||
var saturation = this.options.saturation || this.defaults.saturation;
|
||||
var brightness = this.options.brightness || this.defaults.brightness;
|
||||
this.foreground = this.options.foreground || this.hsl2rgb(hue, saturation, brightness);
|
||||
};
|
||||
|
||||
Identicon.prototype = {
|
||||
background: null,
|
||||
foreground: null,
|
||||
hash: null,
|
||||
margin: null,
|
||||
size: null,
|
||||
format: null,
|
||||
|
||||
image: function(){
|
||||
return this.isSvg()
|
||||
? new Svg(this.size, this.foreground, this.background)
|
||||
: new PNGlib(this.size, this.size, 256);
|
||||
},
|
||||
|
||||
render: function(){
|
||||
var image = this.image(),
|
||||
size = this.size,
|
||||
baseMargin = Math.floor(size * this.margin),
|
||||
cell = Math.floor((size - (baseMargin * 2)) / 5),
|
||||
margin = Math.floor((size - cell * 5) / 2),
|
||||
bg = image.color.apply(image, this.background),
|
||||
fg = image.color.apply(image, this.foreground);
|
||||
|
||||
// the first 15 characters of the hash control the pixels (even/odd)
|
||||
// they are drawn down the middle first, then mirrored outwards
|
||||
var i, color;
|
||||
for (i = 0; i < 15; i++) {
|
||||
color = parseInt(this.hash.charAt(i), 16) % 2 ? bg : fg;
|
||||
if (i < 5) {
|
||||
this.rectangle(2 * cell + margin, i * cell + margin, cell, cell, color, image);
|
||||
} else if (i < 10) {
|
||||
this.rectangle(1 * cell + margin, (i - 5) * cell + margin, cell, cell, color, image);
|
||||
this.rectangle(3 * cell + margin, (i - 5) * cell + margin, cell, cell, color, image);
|
||||
} else if (i < 15) {
|
||||
this.rectangle(0 * cell + margin, (i - 10) * cell + margin, cell, cell, color, image);
|
||||
this.rectangle(4 * cell + margin, (i - 10) * cell + margin, cell, cell, color, image);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
rectangle: function(x, y, w, h, color, image){
|
||||
if (this.isSvg()) {
|
||||
image.rectangles.push({x: x, y: y, w: w, h: h, color: color});
|
||||
} else {
|
||||
var i, j;
|
||||
for (i = x; i < x + w; i++) {
|
||||
for (j = y; j < y + h; j++) {
|
||||
image.buffer[image.index(i, j)] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// adapted from: https://gist.github.com/aemkei/1325937
|
||||
hsl2rgb: function(h, s, b){
|
||||
h *= 6;
|
||||
s = [
|
||||
b += s *= b < .5 ? b : 1 - b,
|
||||
b - h % 1 * s * 2,
|
||||
b -= s *= 2,
|
||||
b,
|
||||
b + h % 1 * s,
|
||||
b + s
|
||||
];
|
||||
|
||||
return[
|
||||
s[ ~~h % 6 ] * 255, // red
|
||||
s[ (h|16) % 6 ] * 255, // green
|
||||
s[ (h|8) % 6 ] * 255 // blue
|
||||
];
|
||||
},
|
||||
|
||||
toString: function(raw){
|
||||
// backward compatibility with old toString, default to base64
|
||||
if (raw) {
|
||||
return this.render().getDump();
|
||||
} else {
|
||||
return this.render().getBase64();
|
||||
}
|
||||
},
|
||||
|
||||
isSvg: function(){
|
||||
return this.format.match(/svg/i)
|
||||
}
|
||||
};
|
||||
|
||||
var Svg = function(size, foreground, background){
|
||||
this.size = size;
|
||||
this.foreground = this.color.apply(this, foreground);
|
||||
this.background = this.color.apply(this, background);
|
||||
this.rectangles = [];
|
||||
};
|
||||
|
||||
Svg.prototype = {
|
||||
size: null,
|
||||
foreground: null,
|
||||
background: null,
|
||||
rectangles: null,
|
||||
|
||||
color: function(r, g, b, a){
|
||||
var values = [r, g, b].map(Math.round);
|
||||
values.push((a >= 0) && (a <= 255) ? a/255 : 1);
|
||||
return 'rgba(' + values.join(',') + ')';
|
||||
},
|
||||
|
||||
getDump: function(){
|
||||
var i,
|
||||
xml,
|
||||
rect,
|
||||
fg = this.foreground,
|
||||
bg = this.background,
|
||||
stroke = this.size * 0.005;
|
||||
|
||||
xml = "<svg xmlns='http://www.w3.org/2000/svg'"
|
||||
+ " width='" + this.size + "' height='" + this.size + "'"
|
||||
+ " style='background-color:" + bg + ";'>"
|
||||
+ "<g style='fill:" + fg + "; stroke:" + fg + "; stroke-width:" + stroke + ";'>";
|
||||
|
||||
for (i = 0; i < this.rectangles.length; i++) {
|
||||
rect = this.rectangles[i];
|
||||
if (rect.color == bg) continue;
|
||||
xml += "<rect "
|
||||
+ " x='" + rect.x + "'"
|
||||
+ " y='" + rect.y + "'"
|
||||
+ " width='" + rect.w + "'"
|
||||
+ " height='" + rect.h + "'"
|
||||
+ "/>";
|
||||
}
|
||||
xml += "</g></svg>"
|
||||
|
||||
return xml;
|
||||
},
|
||||
|
||||
getBase64: function(){
|
||||
if (btoa) {
|
||||
return btoa(this.getDump());
|
||||
} else if (Buffer) {
|
||||
return new Buffer(this.getDump(), 'binary').toString('base64');
|
||||
} else {
|
||||
throw 'Cannot generate base64 output';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||||
module.exports = Identicon;
|
||||
} else {
|
||||
window.Identicon = Identicon;
|
||||
}
|
||||
})();
|
19
assets/3rdparty/identicon.js/package.json
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "identicon.js",
|
||||
"version": "2.3.2",
|
||||
"description": "GitHub-style identicons as PNGs or SVGs in JS.",
|
||||
"main": "identicon.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/stewartlord/identicon.js"
|
||||
},
|
||||
"keywords": [
|
||||
"identicon"
|
||||
],
|
||||
"author": "stewardlord",
|
||||
"license": "BSD",
|
||||
"bugs": {
|
||||
"url": "https://github.com/stewartlord/identicon.js/issues"
|
||||
},
|
||||
"homepage": "https://github.com/stewartlord/identicon.js"
|
||||
}
|
214
assets/3rdparty/identicon.js/pnglib.js
vendored
Normal file
@ -0,0 +1,214 @@
|
||||
/**
|
||||
* A handy class to calculate color values.
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Robert Eisele <robert@xarg.org>
|
||||
* @copyright Copyright (c) 2010, Robert Eisele
|
||||
* @link http://www.xarg.org/2010/03/generate-client-side-png-files-using-javascript/
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
// helper functions for that ctx
|
||||
function write(buffer, offs) {
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
for (var j = 0; j < arguments[i].length; j++) {
|
||||
buffer[offs++] = arguments[i].charAt(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function byte2(w) {
|
||||
return String.fromCharCode((w >> 8) & 255, w & 255);
|
||||
}
|
||||
|
||||
function byte4(w) {
|
||||
return String.fromCharCode((w >> 24) & 255, (w >> 16) & 255, (w >> 8) & 255, w & 255);
|
||||
}
|
||||
|
||||
function byte2lsb(w) {
|
||||
return String.fromCharCode(w & 255, (w >> 8) & 255);
|
||||
}
|
||||
|
||||
// modified from original source to support NPM
|
||||
var PNGlib = function(width,height,depth) {
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.depth = depth;
|
||||
|
||||
// pixel data and row filter identifier size
|
||||
this.pix_size = height * (width + 1);
|
||||
|
||||
// deflate header, pix_size, block headers, adler32 checksum
|
||||
this.data_size = 2 + this.pix_size + 5 * Math.floor((0xfffe + this.pix_size) / 0xffff) + 4;
|
||||
|
||||
// offsets and sizes of Png chunks
|
||||
this.ihdr_offs = 0; // IHDR offset and size
|
||||
this.ihdr_size = 4 + 4 + 13 + 4;
|
||||
this.plte_offs = this.ihdr_offs + this.ihdr_size; // PLTE offset and size
|
||||
this.plte_size = 4 + 4 + 3 * depth + 4;
|
||||
this.trns_offs = this.plte_offs + this.plte_size; // tRNS offset and size
|
||||
this.trns_size = 4 + 4 + depth + 4;
|
||||
this.idat_offs = this.trns_offs + this.trns_size; // IDAT offset and size
|
||||
this.idat_size = 4 + 4 + this.data_size + 4;
|
||||
this.iend_offs = this.idat_offs + this.idat_size; // IEND offset and size
|
||||
this.iend_size = 4 + 4 + 4;
|
||||
this.buffer_size = this.iend_offs + this.iend_size; // total PNG size
|
||||
|
||||
this.buffer = new Array();
|
||||
this.palette = new Object();
|
||||
this.pindex = 0;
|
||||
|
||||
var _crc32 = new Array();
|
||||
|
||||
// initialize buffer with zero bytes
|
||||
for (var i = 0; i < this.buffer_size; i++) {
|
||||
this.buffer[i] = "\x00";
|
||||
}
|
||||
|
||||
// initialize non-zero elements
|
||||
write(this.buffer, this.ihdr_offs, byte4(this.ihdr_size - 12), 'IHDR', byte4(width), byte4(height), "\x08\x03");
|
||||
write(this.buffer, this.plte_offs, byte4(this.plte_size - 12), 'PLTE');
|
||||
write(this.buffer, this.trns_offs, byte4(this.trns_size - 12), 'tRNS');
|
||||
write(this.buffer, this.idat_offs, byte4(this.idat_size - 12), 'IDAT');
|
||||
write(this.buffer, this.iend_offs, byte4(this.iend_size - 12), 'IEND');
|
||||
|
||||
// initialize deflate header
|
||||
var header = ((8 + (7 << 4)) << 8) | (3 << 6);
|
||||
header+= 31 - (header % 31);
|
||||
|
||||
write(this.buffer, this.idat_offs + 8, byte2(header));
|
||||
|
||||
// initialize deflate block headers
|
||||
for (var i = 0; (i << 16) - 1 < this.pix_size; i++) {
|
||||
var size, bits;
|
||||
if (i + 0xffff < this.pix_size) {
|
||||
size = 0xffff;
|
||||
bits = "\x00";
|
||||
} else {
|
||||
size = this.pix_size - (i << 16) - i;
|
||||
bits = "\x01";
|
||||
}
|
||||
write(this.buffer, this.idat_offs + 8 + 2 + (i << 16) + (i << 2), bits, byte2lsb(size), byte2lsb(~size));
|
||||
}
|
||||
|
||||
/* Create crc32 lookup table */
|
||||
for (var i = 0; i < 256; i++) {
|
||||
var c = i;
|
||||
for (var j = 0; j < 8; j++) {
|
||||
if (c & 1) {
|
||||
c = -306674912 ^ ((c >> 1) & 0x7fffffff);
|
||||
} else {
|
||||
c = (c >> 1) & 0x7fffffff;
|
||||
}
|
||||
}
|
||||
_crc32[i] = c;
|
||||
}
|
||||
|
||||
// compute the index into a png for a given pixel
|
||||
this.index = function(x,y) {
|
||||
var i = y * (this.width + 1) + x + 1;
|
||||
var j = this.idat_offs + 8 + 2 + 5 * Math.floor((i / 0xffff) + 1) + i;
|
||||
return j;
|
||||
}
|
||||
|
||||
// convert a color and build up the palette
|
||||
this.color = function(red, green, blue, alpha) {
|
||||
|
||||
alpha = alpha >= 0 ? alpha : 255;
|
||||
var color = (((((alpha << 8) | red) << 8) | green) << 8) | blue;
|
||||
|
||||
if (typeof this.palette[color] == "undefined") {
|
||||
if (this.pindex == this.depth) return "\x00";
|
||||
|
||||
var ndx = this.plte_offs + 8 + 3 * this.pindex;
|
||||
|
||||
this.buffer[ndx + 0] = String.fromCharCode(red);
|
||||
this.buffer[ndx + 1] = String.fromCharCode(green);
|
||||
this.buffer[ndx + 2] = String.fromCharCode(blue);
|
||||
this.buffer[this.trns_offs+8+this.pindex] = String.fromCharCode(alpha);
|
||||
|
||||
this.palette[color] = String.fromCharCode(this.pindex++);
|
||||
}
|
||||
return this.palette[color];
|
||||
}
|
||||
|
||||
// output a PNG string, Base64 encoded
|
||||
this.getBase64 = function() {
|
||||
|
||||
var s = this.getDump();
|
||||
|
||||
var ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
var c1, c2, c3, e1, e2, e3, e4;
|
||||
var l = s.length;
|
||||
var i = 0;
|
||||
var r = "";
|
||||
|
||||
do {
|
||||
c1 = s.charCodeAt(i);
|
||||
e1 = c1 >> 2;
|
||||
c2 = s.charCodeAt(i+1);
|
||||
e2 = ((c1 & 3) << 4) | (c2 >> 4);
|
||||
c3 = s.charCodeAt(i+2);
|
||||
if (l < i+2) { e3 = 64; } else { e3 = ((c2 & 0xf) << 2) | (c3 >> 6); }
|
||||
if (l < i+3) { e4 = 64; } else { e4 = c3 & 0x3f; }
|
||||
r+= ch.charAt(e1) + ch.charAt(e2) + ch.charAt(e3) + ch.charAt(e4);
|
||||
} while ((i+= 3) < l);
|
||||
return r;
|
||||
}
|
||||
|
||||
// output a PNG string
|
||||
this.getDump = function() {
|
||||
|
||||
// compute adler32 of output pixels + row filter bytes
|
||||
var BASE = 65521; /* largest prime smaller than 65536 */
|
||||
var NMAX = 5552; /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||
var s1 = 1;
|
||||
var s2 = 0;
|
||||
var n = NMAX;
|
||||
|
||||
for (var y = 0; y < this.height; y++) {
|
||||
for (var x = -1; x < this.width; x++) {
|
||||
s1+= this.buffer[this.index(x, y)].charCodeAt(0);
|
||||
s2+= s1;
|
||||
if ((n-= 1) == 0) {
|
||||
s1%= BASE;
|
||||
s2%= BASE;
|
||||
n = NMAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
s1%= BASE;
|
||||
s2%= BASE;
|
||||
write(this.buffer, this.idat_offs + this.idat_size - 8, byte4((s2 << 16) | s1));
|
||||
|
||||
// compute crc32 of the PNG chunks
|
||||
function crc32(png, offs, size) {
|
||||
var crc = -1;
|
||||
for (var i = 4; i < size-4; i += 1) {
|
||||
crc = _crc32[(crc ^ png[offs+i].charCodeAt(0)) & 0xff] ^ ((crc >> 8) & 0x00ffffff);
|
||||
}
|
||||
write(png, offs+size-4, byte4(crc ^ -1));
|
||||
}
|
||||
|
||||
crc32(this.buffer, this.ihdr_offs, this.ihdr_size);
|
||||
crc32(this.buffer, this.plte_offs, this.plte_size);
|
||||
crc32(this.buffer, this.trns_offs, this.trns_size);
|
||||
crc32(this.buffer, this.idat_offs, this.idat_size);
|
||||
crc32(this.buffer, this.iend_offs, this.iend_size);
|
||||
|
||||
// convert PNG to string
|
||||
return "\x89PNG\r\n\x1a\n"+this.buffer.join('');
|
||||
}
|
||||
}
|
||||
|
||||
// modified from original source to support NPM
|
||||
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
||||
module.exports = PNGlib;
|
||||
} else {
|
||||
window.PNGlib = PNGlib;
|
||||
}
|
||||
})();
|
121
assets/3rdparty/jszip-utils/jszip-utils.js
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
/*!
|
||||
|
||||
JSZipUtils - A collection of cross-browser utilities to go along with JSZip.
|
||||
<http://stuk.github.io/jszip-utils>
|
||||
|
||||
(c) 2014 Stuart Knightley, David Duponchel
|
||||
Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip-utils/master/LICENSE.markdown.
|
||||
|
||||
*/
|
||||
!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.JSZipUtils=e():"undefined"!=typeof global?global.JSZipUtils=e():"undefined"!=typeof self&&(self.JSZipUtils=e())}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
var JSZipUtils = {};
|
||||
// just use the responseText with xhr1, response with xhr2.
|
||||
// The transformation doesn't throw away high-order byte (with responseText)
|
||||
// because JSZip handles that case. If not used with JSZip, you may need to
|
||||
// do it, see https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data
|
||||
JSZipUtils._getBinaryFromXHR = function (xhr) {
|
||||
// for xhr.responseText, the 0xFF mask is applied by JSZip
|
||||
return xhr.response || xhr.responseText;
|
||||
};
|
||||
|
||||
// taken from jQuery
|
||||
function createStandardXHR() {
|
||||
try {
|
||||
return new window.XMLHttpRequest();
|
||||
} catch( e ) {}
|
||||
}
|
||||
|
||||
function createActiveXHR() {
|
||||
try {
|
||||
return new window.ActiveXObject("Microsoft.XMLHTTP");
|
||||
} catch( e ) {}
|
||||
}
|
||||
|
||||
// Create the request object
|
||||
var createXHR = window.ActiveXObject ?
|
||||
/* Microsoft failed to properly
|
||||
* implement the XMLHttpRequest in IE7 (can't request local files),
|
||||
* so we use the ActiveXObject when it is available
|
||||
* Additionally XMLHttpRequest can be disabled in IE7/IE8 so
|
||||
* we need a fallback.
|
||||
*/
|
||||
function() {
|
||||
return createStandardXHR() || createActiveXHR();
|
||||
} :
|
||||
// For all other browsers, use the standard XMLHttpRequest object
|
||||
createStandardXHR;
|
||||
|
||||
|
||||
|
||||
JSZipUtils.getBinaryContent = function(path, callback) {
|
||||
/*
|
||||
* Here is the tricky part : getting the data.
|
||||
* In firefox/chrome/opera/... setting the mimeType to 'text/plain; charset=x-user-defined'
|
||||
* is enough, the result is in the standard xhr.responseText.
|
||||
* cf https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest#Receiving_binary_data_in_older_browsers
|
||||
* In IE <= 9, we must use (the IE only) attribute responseBody
|
||||
* (for binary data, its content is different from responseText).
|
||||
* In IE 10, the 'charset=x-user-defined' trick doesn't work, only the
|
||||
* responseType will work :
|
||||
* http://msdn.microsoft.com/en-us/library/ie/hh673569%28v=vs.85%29.aspx#Binary_Object_upload_and_download
|
||||
*
|
||||
* I'd like to use jQuery to avoid this XHR madness, but it doesn't support
|
||||
* the responseType attribute : http://bugs.jquery.com/ticket/11461
|
||||
*/
|
||||
try {
|
||||
|
||||
var xhr = createXHR();
|
||||
|
||||
xhr.open('GET', path, true);
|
||||
|
||||
// recent browsers
|
||||
if ("responseType" in xhr) {
|
||||
xhr.responseType = "arraybuffer";
|
||||
}
|
||||
|
||||
// older browser
|
||||
if(xhr.overrideMimeType) {
|
||||
xhr.overrideMimeType("text/plain; charset=x-user-defined");
|
||||
}
|
||||
|
||||
//Allow big files download
|
||||
xhr.setRequestHeader("Range", "bytes=0-9999999999999999999999999999999");
|
||||
|
||||
xhr.onreadystatechange = function(evt) {
|
||||
var file, err;
|
||||
// use `xhr` and not `this`... thanks IE
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200 || xhr.status === 0) {
|
||||
file = null;
|
||||
err = null;
|
||||
try {
|
||||
file = JSZipUtils._getBinaryFromXHR(xhr);
|
||||
} catch(e) {
|
||||
err = new Error(e);
|
||||
}
|
||||
callback(err, file);
|
||||
} else {
|
||||
callback(new Error("Ajax error for " + path + " : " + this.status + " " + this.statusText), null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send();
|
||||
|
||||
} catch (e) {
|
||||
callback(new Error(e), null);
|
||||
}
|
||||
};
|
||||
|
||||
// export
|
||||
module.exports = JSZipUtils;
|
||||
|
||||
// enforcing Stuk's coding style
|
||||
// vim: set shiftwidth=4 softtabstop=4:
|
||||
|
||||
},{}]},{},[1])
|
||||
(1)
|
||||
});
|
||||
;
|
10
assets/3rdparty/jszip-utils/jszip-utils.min.js
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/*!
|
||||
|
||||
JSZipUtils - A collection of cross-browser utilities to go along with JSZip.
|
||||
<http://stuk.github.io/jszip-utils>
|
||||
|
||||
(c) 2014 Stuart Knightley, David Duponchel
|
||||
Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip-utils/master/LICENSE.markdown.
|
||||
|
||||
*/
|
||||
!function(a){"object"==typeof exports?module.exports=a():"function"==typeof define&&define.amd?define(a):"undefined"!=typeof window?window.JSZipUtils=a():"undefined"!=typeof global?global.JSZipUtils=a():"undefined"!=typeof self&&(self.JSZipUtils=a())}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b){"use strict";function c(){try{return new window.XMLHttpRequest}catch(a){}}function d(){try{return new window.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}}var e={};e._getBinaryFromXHR=function(a){return a.response||a.responseText};var f=window.ActiveXObject?function(){return c()||d()}:c;e.getBinaryContent=function(a,b){try{var c=f();c.open("GET",a,!0),"responseType"in c&&(c.responseType="arraybuffer"),c.overrideMimeType&&c.overrideMimeType("text/plain; charset=x-user-defined"),c.onreadystatechange=function(){var d,f;if(4===c.readyState)if(200===c.status||0===c.status){d=null,f=null;try{d=e._getBinaryFromXHR(c)}catch(g){f=new Error(g)}b(f,d)}else b(new Error("Ajax error for "+a+" : "+this.status+" "+this.statusText),null)},c.send()}catch(d){b(new Error(d),null)}},b.exports=e},{}]},{},[1])(1)});
|
11623
assets/3rdparty/jszip/jszip.js
vendored
Normal file
15
assets/3rdparty/jszip/jszip.min.js
vendored
Normal file
9
assets/css/common/page/error.css
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Errors pages stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.error-page .error-content p {
|
||||
word-wrap: break-word;
|
||||
}
|
@ -20,6 +20,29 @@ header .dropdown .fa-gear {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.main-header .alternate-latest-posts-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 360px) {
|
||||
.main-header[forActiveUser="true"] .navbar-brand {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main-header .alternate-latest-posts-button {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nav > li > a {
|
||||
padding: 10px 10px;
|
||||
}
|
||||
|
||||
.navbar-custom-menu > .navbar-nav > li > .dropdown-menu {
|
||||
width: 100%;
|
||||
left: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.skin-blue .main-header .navbar .dropdown-user-menu-action .dropdown-menu li a {
|
||||
color: #333 !important;
|
||||
|
483
assets/css/dark_theme.css
Normal file
@ -0,0 +1,483 @@
|
||||
/**
|
||||
* ComunicWeb dark theme
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
/**
|
||||
* General definitions
|
||||
*/
|
||||
:root {
|
||||
--black: #1119;
|
||||
--black2: #111111;
|
||||
--black3: #000;
|
||||
--black4: #686a6c;
|
||||
--black5: #232426;
|
||||
--black6: #0f0f0f;
|
||||
--white: silver;
|
||||
}
|
||||
|
||||
p, h1, h2, h3, h4, h5, h6 {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
background-color: var(--black3);
|
||||
}
|
||||
|
||||
.link-black {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.table-hover > tbody > tr:hover {
|
||||
background-color: var(--black3);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Buttons
|
||||
*/
|
||||
.btn {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-success,
|
||||
.btn-default,
|
||||
.btn-danger,
|
||||
.btn-info {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.btn-default:active, .btn-default:focus {
|
||||
background-color: var(--white);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Forms
|
||||
*/
|
||||
.form-control {
|
||||
background-color: var(--black);
|
||||
color: var(--white);
|
||||
border-color: var(--black5);
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
background-color: var(--black5);
|
||||
border-color: var(--black4);
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.form-control[disabled],
|
||||
.form-control[readonly],
|
||||
fieldset[disabled] .form-control {
|
||||
background-color: var(--black6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Boxes
|
||||
*/
|
||||
.box {
|
||||
background-color: var(--black5);
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.box-footer {
|
||||
background-color: var(--black5);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Modals
|
||||
*/
|
||||
.modal-header,
|
||||
.modal-footer {
|
||||
background-color: var(--black5);
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
background-color: var(--black6);
|
||||
}
|
||||
|
||||
.modal-primary .modal-header,
|
||||
.modal-primary .modal-footer {
|
||||
background-color: var(--black5) !important;;
|
||||
}
|
||||
|
||||
.modal-primary .modal-body {
|
||||
background-color: var(--black6) !important;
|
||||
}
|
||||
|
||||
.modal-danger .modal-header,
|
||||
.modal-danger .modal-footer {
|
||||
background-color: #a22819 !important;
|
||||
}
|
||||
|
||||
.modal-danger .modal-body {
|
||||
background-color: #872f24 !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dropdown menus
|
||||
*/
|
||||
.dropdown-menu {
|
||||
background-color: var(--black5) !important;
|
||||
}
|
||||
|
||||
.dropdown-menu > li > a {
|
||||
color: var(--white) !important;
|
||||
}
|
||||
|
||||
.dropdown-menu > li > a:hover {
|
||||
background-color: var(--black3) !important;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Navbar
|
||||
*/
|
||||
.navbar {
|
||||
background-color: var(--black6) !important;;
|
||||
}
|
||||
|
||||
.navbar-nav > .notifications-menu > .dropdown-menu > li.header,
|
||||
.navbar-nav > .messages-menu > .dropdown-menu > li.header,
|
||||
.navbar-nav > .tasks-menu > .dropdown-menu > li.header {
|
||||
background-color: var(--black6);
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a,
|
||||
.navbar-nav > .messages-menu > .dropdown-menu > li.footer > a,
|
||||
.navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a {
|
||||
background-color: var(--black6) !important;
|
||||
color: var(--white) !important;
|
||||
}
|
||||
|
||||
.main-header #navbar-search-input.form-control:focus,
|
||||
.main-header #navbar-search-input.form-control:active {
|
||||
background-color: var(--black3);
|
||||
}
|
||||
|
||||
.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a:hover,
|
||||
.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:hover,
|
||||
.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a:hover {
|
||||
background-color: var(--black6);
|
||||
}
|
||||
|
||||
.skin-blue .main-header .navbar .dropdown-user-menu-action .dropdown-menu li a {
|
||||
color: var(--white) !important;;
|
||||
}
|
||||
|
||||
.skin-blue .main-header .navbar .nav > li > a:hover,
|
||||
.skin-blue .main-header .navbar .nav > li > a:active,
|
||||
.skin-blue .main-header .navbar .nav > li > a:focus,
|
||||
.skin-blue .main-header .navbar .nav .open > a,
|
||||
.skin-blue .main-header .navbar .nav .open > a:hover,
|
||||
.skin-blue .main-header .navbar .nav .open > a:focus,
|
||||
.skin-blue .main-header .navbar .nav > .active > a {
|
||||
background-color: var(--black4);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Footer
|
||||
*/
|
||||
.main-footer {
|
||||
background-color: var(--black3);
|
||||
}
|
||||
|
||||
.main-footer span {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Friends list
|
||||
*/
|
||||
@media screen and (min-width: 1200px) {
|
||||
|
||||
#friendsList {
|
||||
background-color: var(--black6);
|
||||
}
|
||||
|
||||
#friendsList:hover {
|
||||
background-color: var(--black5);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) and (min-width: 513px) {
|
||||
#friendsList {
|
||||
background-color: var(--black5);
|
||||
}
|
||||
}
|
||||
|
||||
#friendsList h4 {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
#friendsList li:hover {
|
||||
background-color: var(--black4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emoji picker
|
||||
*/
|
||||
.wdt-emoji-popup {
|
||||
background-color: var(--black6);
|
||||
border: 1px var(--black6) solid;
|
||||
border-radius: 2;
|
||||
}
|
||||
|
||||
#wdt-emoji-menu-header {
|
||||
background-color: var(--black5);
|
||||
}
|
||||
|
||||
#wdt-emoji-footer {
|
||||
background-color: var(--black5);
|
||||
}
|
||||
|
||||
.wdt-emoji-popup h3 {
|
||||
background-color: var(--black4);
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
#wdt-emoji-search {
|
||||
background-color: var(--black5);
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
#wdt-emoji-search:focus {
|
||||
background-color: var(--black4);
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.wdt-emoji:hover {
|
||||
background-color: var(--black4) !important;;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversations
|
||||
*/
|
||||
.open-conversation-button {
|
||||
background-color: var(--black5);
|
||||
}
|
||||
|
||||
.nav-stacked > li > a {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.conversations-list-box .last-activity {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.nav > li > a:hover,
|
||||
.nav > li > a:active,
|
||||
.nav > li > a:focus {
|
||||
color: var(--black5);
|
||||
}
|
||||
|
||||
.select2-dropdown {
|
||||
background-color: var(--black5);
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.select2-container--default .select2-results__option--highlighted[aria-selected] {
|
||||
background-color: var(--black4);
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
#conversationsElem .create-message-form .btn.btn-add-emoji:hover,
|
||||
#conversationsElem .create-message-form .btn.btn-add-image:hover {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
/**
|
||||
* Home page
|
||||
*/
|
||||
#homeLandingScreen {
|
||||
background-image: none !important;
|
||||
background-color: var(--black5);
|
||||
}
|
||||
|
||||
#homeLandingScreen #homeMessage {
|
||||
background-color: var(--black);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Login page
|
||||
*/
|
||||
.login-page, .register-page {
|
||||
background-color: var(--black2);
|
||||
}
|
||||
|
||||
.login-box-body {
|
||||
background-color: var(--black3);
|
||||
}
|
||||
|
||||
.login-logo b, #loginForm label {
|
||||
color: var(--white) !important;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create account page
|
||||
*/
|
||||
.create-account-form label {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* User information
|
||||
*/
|
||||
.list-group-item {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Posts
|
||||
*/
|
||||
.attachment-block {
|
||||
background-color: var(--black6);
|
||||
}
|
||||
|
||||
.post-comments {
|
||||
background-color: var(--black);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.post {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.post-image {
|
||||
filter: brightness(80%);
|
||||
transition: filter 1s;
|
||||
}
|
||||
|
||||
.post-image:hover {
|
||||
filter: brightness(100%);
|
||||
}
|
||||
|
||||
.box-comments .username,
|
||||
.box-comments .comment-content {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
|
||||
.comment-creation-form .comment-image-select a,
|
||||
.comment-creation-form .comment-emoji-select a {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Posts creation form
|
||||
*/
|
||||
|
||||
.post-form-choice span {
|
||||
color: var(--black4);
|
||||
}
|
||||
|
||||
.post-form .post-form-choice input:checked ~ span {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.datepicker.dropdown-menu {
|
||||
background-color: var(--black6);
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.select2-container--default .select2-selection--multiple {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.post-form .post-visiblity-container span {
|
||||
color: var(--black4);
|
||||
}
|
||||
|
||||
.post-form .post-visiblity-container input:checked ~ span {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Posts edit modal
|
||||
*/
|
||||
.editor {
|
||||
background-color: var(--black5);
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search page
|
||||
*/
|
||||
.nav > li > a:hover,
|
||||
.nav > li > a:active,
|
||||
.nav > li > a:focus {
|
||||
background-color: var(--black4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversation page
|
||||
*/
|
||||
.conversations-page-container a {
|
||||
background-color: var(--black6) !important;;
|
||||
}
|
||||
|
||||
.conversations-page-container a {
|
||||
color: var(--white) !important;
|
||||
}
|
||||
|
||||
.conversations-page-container a:hover {
|
||||
background-color: var(--black5) !important;;
|
||||
}
|
||||
|
||||
.conversations-page-container a:active {
|
||||
background-color: var(--black6) !important;;
|
||||
}
|
||||
|
||||
.conversations-page-container a.selected {
|
||||
background-color: var(--black5) !important;;
|
||||
}
|
||||
|
||||
.conversations-page-container .box-conversation .input-group-btn .btn {
|
||||
background-color: var(--black5);
|
||||
}
|
||||
|
||||
.conversations-page-container .box-conversation .input-group-btn .btn:hover {
|
||||
background-color: var(--black4);
|
||||
color: var(--black6);
|
||||
}
|
||||
|
||||
.conversations-page-container .box-conversation .input-group-btn .btn:focus,
|
||||
.conversations-page-container .box-conversation .input-group-btn .btn:active {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.big-box-conversation .direct-chat-text .a,
|
||||
.big-box-conversation .direct-chat-text a {
|
||||
background-color: transparent !important;
|
||||
color: inherit !important;
|
||||
}
|
29
assets/css/pages/conversations/conversation.css
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Conversation pane stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.big-box-conversation .direct-chat-text {
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
max-width: 150px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.big-box-conversation .right .direct-chat-text {
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.big-box-conversation .direct-chat-text .message-img {
|
||||
max-width: 100%;
|
||||
max-height: 200px;
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.big-box-conversation .direct-chat-text .a,
|
||||
.big-box-conversation .direct-chat-text a {
|
||||
color: white;
|
||||
}
|
17
assets/css/pages/conversations/listPane.css
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Conversations list pane
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.conversations-page-container .conversations-list-box {
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.conversations-page-container .conversations-list-box ul {
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.conversations-page-container a.selected {
|
||||
background: #f7f7f7;
|
||||
}
|
17
assets/css/pages/conversations/main.css
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Conversations page main script file
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.conversations-page-container {
|
||||
max-width: 1000px;
|
||||
margin: auto;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
|
||||
.conversations-page-container .conv-list-loading-msg {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
25
assets/css/pages/groups/pages/create.css
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Create groups page main stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.create-group-page {
|
||||
max-width: 450px;
|
||||
margin: auto;
|
||||
padding-top: 60px;
|
||||
}
|
||||
|
||||
.create-group-page form {
|
||||
border: 1px #162935 solid;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.create-group-page form h3 {
|
||||
text-align: center;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.create-group-page .submit-button-container {
|
||||
text-align: center;
|
||||
}
|
22
assets/css/pages/groups/pages/forbidden.css
Normal file
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Access forbidden to page groups stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.group-forbidden-page-container {
|
||||
max-width: 300px;
|
||||
margin: auto;
|
||||
margin-top: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.group-forbidden-page-container .group-logo {
|
||||
width: 130px;
|
||||
margin: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.group-forbidden-page-container .group-name {
|
||||
margin-bottom: 15px;
|
||||
}
|
14
assets/css/pages/groups/pages/group.css
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Group page main stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.group-page {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.group-page .col-md-6 {
|
||||
margin: auto;
|
||||
float: none;
|
||||
}
|
54
assets/css/pages/groups/pages/main.css
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Groups main page stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.groups-main-page {
|
||||
max-width: 450px;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.groups-main-page .group-item {
|
||||
text-align: justify;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.groups-main-page .group-item .group-icon {
|
||||
max-width: 50px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.groups-main-page .group-item div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.groups-main-page .group-item .group-name {
|
||||
width: 180px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.groups-main-page .group-item .buttons-area {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.groups-main-page .group-item .buttons-area .fa {
|
||||
color: #b5bbc8;
|
||||
}
|
||||
|
||||
.groups-main-page .group-item .buttons-area .fa:active {
|
||||
color: black;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 450px){
|
||||
|
||||
.groups-main-page {
|
||||
max-width: 317px;
|
||||
}
|
||||
|
||||
.groups-main-page .group-item .group-name {
|
||||
width: 120px;
|
||||
}
|
||||
}
|
55
assets/css/pages/groups/pages/members.css
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Groups members page stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.group-members-page {
|
||||
float: none;
|
||||
margin: auto;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.group-members-page .backward-link {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.group-members-page .title {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.group-members-page .member {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.group-members-page .member div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.group-members-page .member .user-image {
|
||||
border-radius: 50%;
|
||||
max-width: 50px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.group-members-page .member .member-name {
|
||||
margin-left: 5px;
|
||||
font-weight: bold;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.group-members-page .member .delete-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.group-members-page .member .delete-link:active {
|
||||
color: #3c8dbc;
|
||||
}
|
||||
|
||||
.group-members-page .member .delete-link {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.group-members-page .member .btn-membership-level {
|
||||
width: 130px;;
|
||||
}
|
38
assets/css/pages/groups/pages/settings.css
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Group settings stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.group-settings-container {
|
||||
float: none;
|
||||
margin: auto;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.group-settings-container .title {
|
||||
text-align: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.group-settings-container .separated-block {
|
||||
margin-top: 25px;
|
||||
margin-bottom: 30px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.group-settings-container .submit-button-container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.group-settings-container .groupLogoSettingsContainer {
|
||||
margin-top: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.group-settings-container .group-logo-settings-img {
|
||||
width: 150px;
|
||||
margin: auto;
|
||||
margin-bottom: 10px;
|
||||
display: block;
|
||||
}
|
37
assets/css/pages/groups/sections/header.css
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Groups header
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
|
||||
.group-header .group-icon {
|
||||
max-height: 150px;
|
||||
}
|
||||
|
||||
.group-header .group-name {
|
||||
font-size: 200%;
|
||||
}
|
||||
|
||||
.group-header .group-tag {
|
||||
color: #6f737b;
|
||||
}
|
||||
|
||||
.group-header .col-info .fa,
|
||||
.group-header .col-metadata .fa {
|
||||
margin-right: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.group-header .group-col-icon {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.group-header .group-col-icon span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.group-header .col-md-4 {
|
||||
display: table;
|
||||
margin: auto;
|
||||
}
|
9
assets/css/pages/groups/sections/membershipBlock.css
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Membership block stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.reject-group-invitation-link {
|
||||
color: #f56954;
|
||||
}
|
9
assets/css/pages/groups/sections/posts.css
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Groups posts section stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.box-group-posts .second-user-area {
|
||||
display: none;
|
||||
}
|
@ -21,4 +21,6 @@
|
||||
.latest-posts-row .col-md-5 {
|
||||
margin: auto;
|
||||
float: none;
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
}
|
18
assets/css/pages/passwordForgotten/mailAdmin.css
Normal file
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Mail admin to reset password
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.reset-password-by-mail-step .title {
|
||||
text-align: center;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.reset-password-by-mail-step p {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.reset-password-by-mail-step .btn-mail {
|
||||
width: 100%;
|
||||
}
|
11
assets/css/pages/passwordForgotten/main.css
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Password forgotten page main stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.box-password-forgotten {
|
||||
max-width: 350px;
|
||||
margin: auto;
|
||||
margin-top: 20px;
|
||||
}
|
14
assets/css/pages/passwordForgotten/promptOption.css
Normal file
@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Password forgotten prompt option section stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.password-reset-prompt-option-section p {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.password-reset-prompt-option-section .btn {
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
}
|
15
assets/css/pages/resetPassword/main.css
Normal file
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Reset password main script
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.reset-password-box {
|
||||
max-width: 300px;
|
||||
margin: auto;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.reset-password-box .btn {
|
||||
display: block;
|
||||
}
|
24
assets/css/pages/search/main.css
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Search page main stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.searchPage {
|
||||
max-width: 500px;
|
||||
margin: auto;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.searchPage .results-container {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
|
||||
.searchPage .results-container li a img {
|
||||
margin: auto 10px auto auto;
|
||||
max-width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
visibility: visible;
|
||||
}
|
5
assets/css/pages/settings/sections/language.css
Normal file
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Settings language section
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
13
assets/css/pages/settings/sections/privacy.css
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Settings privacy settings section
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.box-export-account-data-settings .btn {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.box-delete-account-settings .btn {
|
||||
float: right;
|
||||
}
|
9
assets/css/pages/userPage/posts.css
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* User posts stylesheet
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
.box-user-posts .second-user-area {
|
||||
display: none;
|
||||
}
|
@ -27,7 +27,7 @@ ComunicWeb.common.date = {
|
||||
|
||||
//Check there was less than one minute
|
||||
if(difference == 0)
|
||||
return seconds + "s";
|
||||
return lang("dates_s", [seconds]);
|
||||
|
||||
|
||||
//Calculate minutes
|
||||
@ -36,7 +36,7 @@ ComunicWeb.common.date = {
|
||||
|
||||
//Check there was less than one hour
|
||||
if(difference == 0)
|
||||
return minutes + "min";
|
||||
return lang("dates_min", [minutes]);
|
||||
|
||||
|
||||
//Calculate hours
|
||||
@ -45,7 +45,7 @@ ComunicWeb.common.date = {
|
||||
|
||||
//Check there was less than a day
|
||||
if(difference == 0)
|
||||
return hours + "h";
|
||||
return lang("dates_h", [hours]);
|
||||
|
||||
|
||||
//Calculate days
|
||||
@ -55,9 +55,9 @@ ComunicWeb.common.date = {
|
||||
//Check there was less than a month
|
||||
if(difference == 0){
|
||||
if(days == 1)
|
||||
return "1 day";
|
||||
return lang("dates_one_day");
|
||||
else
|
||||
return days + " days";
|
||||
return lang("dates_days", [days]);
|
||||
}
|
||||
|
||||
|
||||
@ -68,19 +68,19 @@ ComunicWeb.common.date = {
|
||||
//Check there was less than a year
|
||||
if(difference == 0){
|
||||
if(months == 1)
|
||||
return "1 month";
|
||||
return lang("dates_one_month");
|
||||
else
|
||||
return months + " months";
|
||||
return lang("dates_months", [months]);
|
||||
}
|
||||
|
||||
|
||||
//Calculate years
|
||||
var years = difference;
|
||||
if(years == 1){
|
||||
return "1 year";
|
||||
return lang("dates_one_year");
|
||||
}
|
||||
else {
|
||||
return years + " years";
|
||||
return lang("dates_years", [years]);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -74,7 +74,7 @@ var ComunicWeb = {
|
||||
/**
|
||||
* Return current language
|
||||
*/
|
||||
getCurrentLanguage: function(){},
|
||||
current: function(){},
|
||||
|
||||
/**
|
||||
* Initializate languages
|
||||
@ -191,6 +191,11 @@ var ComunicWeb = {
|
||||
*/
|
||||
refresh_current_page: function(){},
|
||||
|
||||
/**
|
||||
* Safely trigger URL update
|
||||
*/
|
||||
update_uri: function(title, uri){},
|
||||
|
||||
/**
|
||||
* Inform of page location update
|
||||
*/
|
||||
@ -392,6 +397,8 @@ var ComunicWeb = {
|
||||
* Logout user
|
||||
*/
|
||||
logoutUser: function(afterLogout){},
|
||||
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
@ -468,6 +475,26 @@ var ComunicWeb = {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Account export
|
||||
*/
|
||||
export: {
|
||||
|
||||
/**
|
||||
* UI controller
|
||||
*/
|
||||
ui: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Worker
|
||||
*/
|
||||
worker: {
|
||||
//TODO: implement
|
||||
},
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
@ -582,10 +609,38 @@ var ComunicWeb = {
|
||||
/**
|
||||
* Search form component
|
||||
*/
|
||||
searchForm: {
|
||||
search: {
|
||||
|
||||
/**
|
||||
* Search form
|
||||
*/
|
||||
form: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Search interface
|
||||
*/
|
||||
interface: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Search results UI
|
||||
*/
|
||||
ui: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Search utilities
|
||||
*/
|
||||
utils: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Settings component
|
||||
*/
|
||||
@ -598,6 +653,13 @@ var ComunicWeb = {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Settings helper
|
||||
*/
|
||||
helper: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
@ -961,8 +1023,48 @@ var ComunicWeb = {
|
||||
//TODO : implement
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Groups component
|
||||
*/
|
||||
groups: {
|
||||
|
||||
/**
|
||||
* API interface
|
||||
*/
|
||||
interface: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Groups utilities
|
||||
*/
|
||||
utils: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Groups information
|
||||
*/
|
||||
info: {
|
||||
//TODO : implement
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Virtual directories component
|
||||
*/
|
||||
virtualDirectory: {
|
||||
|
||||
/**
|
||||
* API interface
|
||||
*/
|
||||
interface: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1100,6 +1202,137 @@ var ComunicWeb = {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Conversations page
|
||||
*/
|
||||
conversations: {
|
||||
|
||||
/**
|
||||
* Main script
|
||||
*/
|
||||
main: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Conversations list pane
|
||||
*/
|
||||
listPane: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Conversation pane
|
||||
*/
|
||||
conversation: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Conversation page utilities
|
||||
*/
|
||||
utils: {
|
||||
//TODO : implement
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Groups page
|
||||
*/
|
||||
groups: {
|
||||
|
||||
/**
|
||||
* Groups page main script
|
||||
*/
|
||||
main: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Groups pages
|
||||
*/
|
||||
pages: {
|
||||
|
||||
/**
|
||||
* Main page
|
||||
*/
|
||||
main: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a group page
|
||||
*/
|
||||
create: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Main group page
|
||||
*/
|
||||
group: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Settings page
|
||||
*/
|
||||
settings: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Group members page
|
||||
*/
|
||||
members: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Access to group forbidden page
|
||||
*/
|
||||
forbidden: {
|
||||
//TODO : implemement
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Groups sections
|
||||
*/
|
||||
sections: {
|
||||
|
||||
/**
|
||||
* Header section
|
||||
*/
|
||||
header: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Membership block
|
||||
*/
|
||||
membershipBlock: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Posts sections
|
||||
*/
|
||||
posts: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Follow block
|
||||
*/
|
||||
followBlock: {
|
||||
//TODO : implement
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* User settings page
|
||||
*/
|
||||
@ -1138,6 +1371,13 @@ var ComunicWeb = {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Language section
|
||||
*/
|
||||
language: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Security section
|
||||
*/
|
||||
@ -1158,6 +1398,13 @@ var ComunicWeb = {
|
||||
accountImage: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Privacy section
|
||||
*/
|
||||
privacy: {
|
||||
//TODO : implement
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -1199,6 +1446,62 @@ var ComunicWeb = {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Password forgotten page
|
||||
*/
|
||||
passwordForgotten: {
|
||||
|
||||
/**
|
||||
* Main script
|
||||
*/
|
||||
main: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Ask user email step
|
||||
*/
|
||||
promptEmail: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Ask user reset option
|
||||
*/
|
||||
promptOption: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Option : send a mail to the admin
|
||||
*/
|
||||
mailAdmin: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
/**
|
||||
* Option : prompt security questions
|
||||
*/
|
||||
promptSecurityQuestions: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Password reset page
|
||||
*/
|
||||
resetPassword: {
|
||||
|
||||
/**
|
||||
* Main script
|
||||
*/
|
||||
main: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Logout controller
|
||||
*/
|
||||
@ -1209,5 +1512,32 @@ var ComunicWeb = {
|
||||
openLogoutPage: function(additionnalData, targetElement){},
|
||||
},
|
||||
|
||||
/**
|
||||
* Virtual directory pages
|
||||
*/
|
||||
virtualDirectory: {
|
||||
|
||||
/**
|
||||
* Main page
|
||||
*/
|
||||
page: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Search page
|
||||
*/
|
||||
search: {
|
||||
|
||||
/**
|
||||
* Main page
|
||||
*/
|
||||
main: {
|
||||
//TODO : implement
|
||||
},
|
||||
|
||||
},
|
||||
},
|
||||
};
|
@ -6,6 +6,22 @@
|
||||
|
||||
ComunicWeb.common.langs = {
|
||||
|
||||
/**
|
||||
* Languages list
|
||||
*/
|
||||
list: {
|
||||
|
||||
en: {
|
||||
name: "English",
|
||||
local_name: "English"
|
||||
},
|
||||
|
||||
fr: {
|
||||
name: "French",
|
||||
local_name: "Français"
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Local storage lang item name
|
||||
*/
|
||||
@ -21,17 +37,25 @@ ComunicWeb.common.langs = {
|
||||
*/
|
||||
__defaultLang: "en",
|
||||
|
||||
|
||||
/**
|
||||
* Get current language
|
||||
*
|
||||
* @return {String} The id of the current language
|
||||
*/
|
||||
getCurrentLanguage: function(){
|
||||
current: function(){
|
||||
|
||||
//Check if a language has been set in local storage
|
||||
if(localStorage.getItem(this._lang_storage_field_name) != null)
|
||||
return localStorage.getItem(this._lang_storage_field_name);
|
||||
|
||||
//Get user language
|
||||
var language = navigator.language || navigator.userLanguage;
|
||||
|
||||
if(language){
|
||||
return language.split("-")[0];
|
||||
}
|
||||
|
||||
//Else return default language
|
||||
return ComunicWeb.__config.defaultLanguage;
|
||||
},
|
||||
@ -61,7 +85,7 @@ ComunicWeb.common.langs = {
|
||||
ComunicWeb.debug.logMessage("Get and install languages...");
|
||||
|
||||
//Get languages to install
|
||||
this.__currentLang = this.getCurrentLanguage();
|
||||
this.__currentLang = this.current();
|
||||
this.__defaultLang = ComunicWeb.__config.defaultLanguage;
|
||||
|
||||
//Everything is OK
|
||||
@ -76,6 +100,10 @@ ComunicWeb.common.langs = {
|
||||
* @return {String} The string ready to show
|
||||
*/
|
||||
getTranslatedText: function(stringName, stringParams){
|
||||
|
||||
if(!this[this.__currentLang])
|
||||
return "Invalid language!";
|
||||
|
||||
//Try to get string
|
||||
if(this[this.__currentLang][stringName])
|
||||
var string = this[this.__currentLang][stringName];
|
||||
|
@ -47,7 +47,7 @@ ComunicWeb.common.messages.createCalloutElem = function(calloutTitle, calloutMes
|
||||
*/
|
||||
ComunicWeb.common.messages.createLoadingCallout = function(target){
|
||||
|
||||
var elem = this.createCalloutElem("Loading", "Please wait while this page is loading...", "info");
|
||||
var elem = this.createCalloutElem(lang("messages_loading_layout_title"), lang("messages_loading_layout_message"), "info");
|
||||
|
||||
if(target)
|
||||
target.appendChild(elem);
|
||||
@ -62,7 +62,7 @@ ComunicWeb.common.messages.createLoadingCallout = function(target){
|
||||
*
|
||||
* @param {object} info Information about the callout to create
|
||||
* @argument {string} type The type of modal
|
||||
* @param {string} title The title of the modal
|
||||
* @argument {string} title The title of the modal
|
||||
* @return {object} Information about the created dialog
|
||||
*/
|
||||
ComunicWeb.common.messages.createDialogSkeleton = function(info){
|
||||
@ -138,7 +138,7 @@ ComunicWeb.common.messages.createDialogSkeleton = function(info){
|
||||
appendTo: data.modalFooter,
|
||||
type: "button",
|
||||
class: "btn btn-default",
|
||||
innerHTML: "Cancel"
|
||||
innerHTML: lang("messages_dialog_cancel")
|
||||
});
|
||||
|
||||
return data;
|
||||
@ -197,7 +197,7 @@ ComunicWeb.common.messages.confirm = function(message, callback){
|
||||
appendTo: modalHeader,
|
||||
type: "h4",
|
||||
class: "modal-title",
|
||||
innerHTML: "Confirm the operation"
|
||||
innerHTML: lang("messages_dialog_confirm_title")
|
||||
});
|
||||
|
||||
//Modal body
|
||||
@ -219,7 +219,7 @@ ComunicWeb.common.messages.confirm = function(message, callback){
|
||||
appendTo: modalFooter,
|
||||
type: "button",
|
||||
class: "btn btn-default pull-left",
|
||||
innerHTML: "Cancel"
|
||||
innerHTML: lang("messages_dialog_confirm_cancel")
|
||||
});
|
||||
cancelButton.setAttribute("data-confirm", "false");
|
||||
|
||||
@ -227,7 +227,7 @@ ComunicWeb.common.messages.confirm = function(message, callback){
|
||||
appendTo: modalFooter,
|
||||
type: "button",
|
||||
class: "btn btn-danger",
|
||||
innerHTML: "Confirm"
|
||||
innerHTML: lang("messages_dialog_confirm_confirm")
|
||||
});
|
||||
confirmButton.setAttribute("data-confirm", "true");
|
||||
|
||||
@ -341,7 +341,7 @@ ComunicWeb.common.messages.inputString = function(title, message, defaultValue,
|
||||
appendTo: modalFooter,
|
||||
type: "button",
|
||||
class: "btn btn-default pull-left",
|
||||
innerHTML: "Cancel"
|
||||
innerHTML: lang("messages_dialog_input_string_cancel")
|
||||
});
|
||||
cancelButton.setAttribute("data-confirm", "false");
|
||||
|
||||
@ -349,7 +349,7 @@ ComunicWeb.common.messages.inputString = function(title, message, defaultValue,
|
||||
appendTo: modalFooter,
|
||||
type: "button",
|
||||
class: "btn btn-primary",
|
||||
innerHTML: "Submit"
|
||||
innerHTML: lang("messages_dialog_input_string_submit")
|
||||
});
|
||||
submitButton.setAttribute("data-confirm", "true");
|
||||
|
||||
|
@ -157,20 +157,23 @@ ComunicWeb.common.page = {
|
||||
firstPartURI = "home";
|
||||
}
|
||||
|
||||
//Save the first part of the URI as an argument
|
||||
additionnalData.rootDirectory = firstPartURI;
|
||||
|
||||
//Check if there is also subfolders
|
||||
if(firstPartURI.indexOf("/") != -1){
|
||||
|
||||
//Save the list of subfolders
|
||||
var subfoldersURIarray = firstPartURI.split("/");
|
||||
subfoldersURIarray.shift();
|
||||
subfoldersURI = subfoldersURIarray.join("/");
|
||||
var subfoldersURI = subfoldersURIarray.join("/");
|
||||
|
||||
//Remove them to find the right page
|
||||
firstPartURI = firstPartURI.split("/")[0];
|
||||
|
||||
} else {
|
||||
//No subfolder was specified
|
||||
subfoldersURI = false;
|
||||
var subfoldersURI = false;
|
||||
}
|
||||
|
||||
//Check if specied page exists
|
||||
@ -180,17 +183,24 @@ ComunicWeb.common.page = {
|
||||
|
||||
//Else we include the 404 not found page
|
||||
else {
|
||||
|
||||
//Check if no subfolder was specified
|
||||
if(subfoldersURI)
|
||||
var pageInfos = ComunicWeb.pagesList.notFound;
|
||||
|
||||
//Find & open dynamically the appropriate page
|
||||
else {
|
||||
var pageInfos = ComunicWeb.pagesList.virtual_directory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Change page title
|
||||
document.title = pageInfos.pageTitle;
|
||||
|
||||
//Change page URL
|
||||
ComunicWeb.common.url.changeURI(document.title, pageURI);
|
||||
|
||||
//Save new url
|
||||
this._current_url = window.location.href.toString();
|
||||
//Change page URL, if required
|
||||
if(additionnalData.no_url_update ? !additionnalData.no_url_update : true)
|
||||
this.update_uri(document.title, pageURI);
|
||||
|
||||
//Get the main container of the page
|
||||
var mainContainerElem = byId("wrapper");
|
||||
@ -200,6 +210,12 @@ ComunicWeb.common.page = {
|
||||
var mainContainerElem = this.emptyPage(true);
|
||||
}
|
||||
|
||||
//Check if the page requires user login
|
||||
if(pageInfos.needLogin){
|
||||
if(!signed_in())
|
||||
openPage("login");
|
||||
}
|
||||
|
||||
//We check if the page is a full screen page or not
|
||||
if(pageInfos.disableMenus){
|
||||
//We force the screen to be cleaned
|
||||
@ -274,7 +290,22 @@ ComunicWeb.common.page = {
|
||||
var currentPage = ComunicWeb.common.url.getCurrentWebsiteURL();
|
||||
|
||||
//Open a page
|
||||
this.openPage(currentPage);
|
||||
this.openPage(currentPage, {no_url_update: true});
|
||||
},
|
||||
|
||||
/**
|
||||
* Safely trigger URL update
|
||||
*
|
||||
* @param {String} title The new title of the page
|
||||
* @param {String} uri The new URL
|
||||
*/
|
||||
update_uri: function(title, uri){
|
||||
|
||||
//Trigger URL update
|
||||
ComunicWeb.common.url.changeURI(title, uri);
|
||||
|
||||
//Save new url
|
||||
this._current_url = window.location.href.toString();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -339,10 +370,25 @@ ComunicWeb.common.page = {
|
||||
}
|
||||
}
|
||||
|
||||
//Apply required translations
|
||||
while(templateContent.includes("[[")){
|
||||
|
||||
//Get the full template inclusion
|
||||
var source = templateContent.match(/\[\[.*\]\]/i)[0];
|
||||
|
||||
//Determine lang key
|
||||
var key = source.replace("[[", "").replace("]]", "");
|
||||
var translation = lang(key);
|
||||
|
||||
//Apply lang
|
||||
while(templateContent.includes(source))
|
||||
templateContent = templateContent.replace(source, translation);
|
||||
}
|
||||
|
||||
//Apply template source
|
||||
targetElem.innerHTML = templateContent;
|
||||
|
||||
//Make a link live
|
||||
//Make links live
|
||||
var aElems = targetElem.getElementsByTagName("a");
|
||||
for(num in aElems){
|
||||
|
||||
|
@ -38,9 +38,36 @@ function openPage(pageURI, additionnalData){
|
||||
* @return {Boolean} True for a success
|
||||
*/
|
||||
function openUserPage(user){
|
||||
if(user.virtualDirectory == "")
|
||||
openUserPageFromID(user.userID);
|
||||
else
|
||||
openPage(user.virtualDirectory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a user page quickly from its user ID
|
||||
*
|
||||
* @param {String} user The ID of the user or its directory
|
||||
* @return {Boolean} True for a success
|
||||
*/
|
||||
function openUserPageFromID(user){
|
||||
return openPage("user/" + user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a group age
|
||||
*
|
||||
* @param {Object} info Information about the target group
|
||||
*/
|
||||
function openGroupPage(info){
|
||||
|
||||
if(info.virtual_directory != "null")
|
||||
openPage(info.virtual_directory);
|
||||
else
|
||||
openPage("groups/" + info.id);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user is signed in or not
|
||||
*
|
||||
@ -124,3 +151,23 @@ function openConversation(id){
|
||||
function notify(message, type, duration, title){
|
||||
ComunicWeb.common.notificationSystem.showNotification(message, type, duration, title)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about a single group
|
||||
*
|
||||
* @param {Number} id The ID of the group to fetch
|
||||
* @param {Function} callback
|
||||
*/
|
||||
function getInfoGroup(id, callback){
|
||||
ComunicWeb.components.groups.info.getInfo(id, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about multiple groups
|
||||
*
|
||||
* @param {Array} IDs The IDs of the groups to get information about
|
||||
* @param {Function} callback Callback to call once we have information about the group
|
||||
*/
|
||||
function getInfoMultipleGroups(IDs, callback){
|
||||
ComunicWeb.components.groups.info.getInfoMultiple(IDs, callback);
|
||||
}
|
@ -19,6 +19,11 @@ ComunicWeb.common.system = {
|
||||
//Start init
|
||||
ComunicWeb.debug.logMessage("Start initialization...");
|
||||
|
||||
//Enable error reporting
|
||||
window.addEventListener("error", function(e){
|
||||
ComunicWeb.common.error.syntaxtError(e.error);
|
||||
});
|
||||
|
||||
//Disable tooltips
|
||||
$(function () {
|
||||
$(document.body).tooltip("disable");
|
||||
@ -52,11 +57,8 @@ ComunicWeb.common.system = {
|
||||
* Open a page
|
||||
*/
|
||||
if(!openPage){
|
||||
//Get current page URI
|
||||
var currentPage = ComunicWeb.common.url.getCurrentWebsiteURL();
|
||||
|
||||
//Open a page
|
||||
ComunicWeb.common.page.openPage(currentPage);
|
||||
//Refresh current page
|
||||
ComunicWeb.common.page.refresh_current_page();
|
||||
}
|
||||
else
|
||||
//Open specified page
|
||||
|
@ -39,6 +39,7 @@ function createElem(nodeType, appendTo){
|
||||
* @info {String} value The value of the new element
|
||||
* @info {String} placeholder The placeholder of the new element
|
||||
* @info {String} innerHTML Specify the html content of the newly created element
|
||||
* @info {String} innerLang Specify the key of the lang to use to fill the element
|
||||
* @info {boolean} disabled Set whether the field should be disabled or not (input only)
|
||||
* @return {HTMLElement} The newly created element
|
||||
*/
|
||||
@ -102,6 +103,9 @@ function createElem2(infos){
|
||||
if(infos.innerHTML)
|
||||
newElem.innerHTML = infos.innerHTML;
|
||||
|
||||
if(infos.innerLang)
|
||||
newElem.innerHTML = lang(infos.innerLang);
|
||||
|
||||
//Set field state
|
||||
if(infos.disabled)
|
||||
infos.disabled = true;
|
||||
@ -460,6 +464,21 @@ function add_space(target){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and append a new paragraph
|
||||
*
|
||||
* @param {HTMLElement} target The target for the new paragraph
|
||||
* @param {String} content The new content for the paragraph
|
||||
* @returns {HTMLElement} Generated element
|
||||
*/
|
||||
function add_p(target, content){
|
||||
return createElem2({
|
||||
appendTo: target,
|
||||
type: "p",
|
||||
innerHTML: content
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current absolute position bottom of the screen
|
||||
*
|
||||
@ -508,3 +527,69 @@ window.location.changed = function(e){};
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
||||
/**
|
||||
* Generate a new random string
|
||||
*
|
||||
* @param {number} length The length of the string ot generate
|
||||
* @return {string} Generated string
|
||||
*/
|
||||
function random_string(length){
|
||||
|
||||
var text = "";
|
||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst0123456789";
|
||||
|
||||
for(var i = 0; i < length; i++)
|
||||
text += possible.charAt(Math.random() * possible.length);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and return a new random identity image
|
||||
*
|
||||
* @return {string} Base64 - encoded new identity image
|
||||
*/
|
||||
function generateIdentImage() {
|
||||
var hash = random_string(32);
|
||||
var color = Math.random() * 240;
|
||||
var color2 = Math.random() * 240;
|
||||
var color3 = Math.random() * 240;
|
||||
var options = {
|
||||
foreground: [color, color2, color3, 255],
|
||||
size: 130,
|
||||
margin: 0.2,
|
||||
format: 'png'
|
||||
};
|
||||
return new Identicon(hash, options).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn a data URI into blob
|
||||
*
|
||||
* This function is based on Stoive answer at StackOverFlow question #4998908
|
||||
*
|
||||
* @param {string} dataURI The URI to process
|
||||
* @return {Blob} generated blob
|
||||
*/
|
||||
function dataURItoBlob(dataURI){
|
||||
|
||||
//convert base64 / URLEncoded data component to raw binary data held in a string
|
||||
var byteString;
|
||||
if(dataURI.split(",")[0].indexOf("base64") >= 0)
|
||||
byteString = atob(dataURI.split(",")[1]);
|
||||
else
|
||||
byteString = unescape(dataURI.split(",")[1]);
|
||||
|
||||
|
||||
//Separate the out the mime component
|
||||
var mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0];
|
||||
|
||||
//Write the bytes of the string to a typed array
|
||||
var ia = new Uint8Array(byteString.length);
|
||||
for(var i = 0; i < byteString.length; i++)
|
||||
ia[i] = byteString.charCodeAt(i);
|
||||
|
||||
return new Blob([ia], {type: mimeString});
|
||||
|
||||
}
|
106
assets/js/components/account/export/ui.js
Normal file
@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Account export UI controller
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
ComunicWeb.components.account.export.ui = {
|
||||
|
||||
/**
|
||||
* Account export modal information
|
||||
*/
|
||||
|
||||
_exportModal: {},
|
||||
|
||||
/**
|
||||
* Request account export
|
||||
*
|
||||
* @param {String} password The password of the user
|
||||
*/
|
||||
requestExport: function(password){
|
||||
|
||||
//Reset modal information
|
||||
this._exportModal = {};
|
||||
|
||||
//Create the modal
|
||||
this._exportModal = ComunicWeb.common.messages.createDialogSkeleton({
|
||||
title: "Exporting data"
|
||||
});
|
||||
var modal = this._exportModal.modal;
|
||||
$(modal).modal("show");
|
||||
|
||||
//Add message
|
||||
createElem2({
|
||||
appendTo: this._exportModal.modalBody,
|
||||
type: "p",
|
||||
innerHTML: "Please do not close this window while we create your archive..."
|
||||
});
|
||||
|
||||
//Add progress bar
|
||||
var progressContainer = createElem2({
|
||||
appendTo: this._exportModal.modalBody,
|
||||
type: "div",
|
||||
class: "progress progress-xs progress-striped active"
|
||||
});
|
||||
this._exportModal.progress = createElem2({
|
||||
appendTo: progressContainer,
|
||||
type: "div",
|
||||
class: "progress-bar progress-bar-success"
|
||||
});
|
||||
this.updateProgress(1);
|
||||
|
||||
//Add message
|
||||
this._exportModal.messageContainer = createElem2({
|
||||
appendTo: this._exportModal.modalBody,
|
||||
type: "p",
|
||||
innerHTML: "Starting..."
|
||||
});
|
||||
|
||||
//Create close modal function
|
||||
var closeModal = function(){
|
||||
$(modal).modal('hide');
|
||||
emptyElem(modal);
|
||||
modal.remove();
|
||||
}
|
||||
this._exportModal.close = closeModal;
|
||||
this._exportModal.closeModal.onclick = closeModal;
|
||||
this._exportModal.cancelButton.onclick = closeModal;
|
||||
|
||||
//Start the worker
|
||||
ComunicWeb.components.account.export.worker.start(password);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the progress of the creation of the archive
|
||||
*
|
||||
* @param {Number} progress The new percentage to apply
|
||||
*/
|
||||
updateProgress: function(progress){
|
||||
this._exportModal.progress.style.width = progress + "%";
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the message shown on the screen
|
||||
*
|
||||
* @param {String} message The new message
|
||||
*/
|
||||
updateMessage: function(message){
|
||||
this._exportModal.messageContainer.innerHTML = message;
|
||||
},
|
||||
|
||||
/**
|
||||
* Display an error that prevent the success of the operation
|
||||
*
|
||||
* @param {String} message The message of the error
|
||||
*/
|
||||
exportFatalError: function(message){
|
||||
|
||||
//Get modal body
|
||||
var modalBody = this._exportModal.modalBody;
|
||||
emptyElem(modalBody);
|
||||
|
||||
//Display the error message
|
||||
var msg = ComunicWeb.common.messages.createCalloutElem("Could not export your data", "An error occurred while trying to export your data: <i>" + message + "</i>", "danger");
|
||||
modalBody.appendChild(msg);
|
||||
}
|
||||
}
|
231
assets/js/components/account/export/worker.js
Normal file
@ -0,0 +1,231 @@
|
||||
/**
|
||||
* Account data export worker
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
ComunicWeb.components.account.export.worker = {
|
||||
|
||||
/**
|
||||
* Start account export
|
||||
*
|
||||
* @param {String} password The password of the user
|
||||
*/
|
||||
start: function(password){
|
||||
|
||||
//Get all user text data from the interface
|
||||
ComunicWeb.components.account.interface.exportData(password, function(result){
|
||||
|
||||
//Check for errors
|
||||
if(result.error){
|
||||
return ComunicWeb.components.account.export.ui.exportFatalError("Could not get text data! Please check your password...");
|
||||
}
|
||||
|
||||
//Update progress
|
||||
ComunicWeb.components.account.export.ui.updateMessage("Got text data");
|
||||
ComunicWeb.components.account.export.ui.updateProgress(10);
|
||||
|
||||
//Parse data
|
||||
ComunicWeb.components.account.export.worker.parse(result);
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Parse account text data into ZIP file
|
||||
*
|
||||
* @param {Object} data Text data about the account
|
||||
*/
|
||||
parse: function(data){
|
||||
|
||||
//Get UI shorcut
|
||||
var ui = ComunicWeb.components.account.export.ui;
|
||||
|
||||
var Promise = window.Promise;
|
||||
if (!Promise) {
|
||||
Promise = JSZip.external.Promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the content and return the associated promise.
|
||||
* @param {String} url the url of the content to fetch.
|
||||
* @return {Promise} the promise containing the data.
|
||||
*/
|
||||
function urlToPromise(url) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
JSZipUtils.getBinaryContent(url, function (err, data) {
|
||||
if(err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform an URL into a path in the archive
|
||||
*
|
||||
* @param {String} url The URL to transform
|
||||
* @return {String} Generated file path
|
||||
*/
|
||||
function urlToPath(url) {
|
||||
var path = url.replace("://", "/");
|
||||
return "files/" + path;
|
||||
}
|
||||
|
||||
//Determine the list of files to download
|
||||
var files_list = this._generate_files_list(data);
|
||||
|
||||
//Create zip file
|
||||
var zip = new JSZip();
|
||||
|
||||
//Add raw json file
|
||||
zip.file("source.json", JSON.stringify(data));
|
||||
|
||||
//Add the files to download
|
||||
files_list.forEach(function(url){
|
||||
var path = urlToPath(url);
|
||||
zip.file(path, urlToPromise(url), {binary:true});
|
||||
});
|
||||
|
||||
//Generated zip archive
|
||||
zip.generateAsync({type:"blob"}, function updateCallback(metadata) {
|
||||
var msg = "progression : " + metadata.percent.toFixed(2) + " %";
|
||||
if(metadata.currentFile) {
|
||||
msg += ", current file = " + metadata.currentFile;
|
||||
}
|
||||
ui.updateMessage(msg);
|
||||
ui.updateProgress(metadata.percent.toFixed(2));
|
||||
})
|
||||
|
||||
//Trigger download
|
||||
.then(function callback(blob) {
|
||||
|
||||
//Download file
|
||||
saveAs(blob, "accountData.zip");
|
||||
|
||||
//Update progress
|
||||
ui.updateProgress(100);
|
||||
ui.updateMessage("Done !");
|
||||
|
||||
}, function (e) {
|
||||
//In case of error
|
||||
ComunicWeb.components.account.export.ui.exportFatalError(e);
|
||||
|
||||
//Update progress
|
||||
ui.updateProgress(100);
|
||||
ui.updateMessage("Error !");
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine the list of files to download
|
||||
*
|
||||
* @param {Object} data Dataset to parse
|
||||
* @return {Array} Generated dataset
|
||||
*/
|
||||
_generate_files_list: function(data){
|
||||
|
||||
var files = [];
|
||||
|
||||
/**
|
||||
* Parse user information to find potential files to download
|
||||
*
|
||||
* @param {Object} info Information about the comment to parse
|
||||
*/
|
||||
var parseUserInfo = function(info){
|
||||
if(info.accountImage != null)
|
||||
if(!files.includes(info.accountImage))
|
||||
files.push(info.accountImage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a comment to find potential files to download
|
||||
*
|
||||
* @param {Object} info Information about the comment to parse
|
||||
*/
|
||||
var parseComment = function(info){
|
||||
if(info.img_url != null)
|
||||
if(!files.includes(info.img_url))
|
||||
files.push(info.img_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a post to find potential files to download
|
||||
*
|
||||
* @param {Object} info Information about the post to parse
|
||||
*/
|
||||
var parsePost = function(post){
|
||||
|
||||
if(post.kind != "youtube"){
|
||||
if(post.file_path_url != null){
|
||||
if(!files.includes(post.file_path_url))
|
||||
files.push(post.file_path_url);
|
||||
}
|
||||
}
|
||||
|
||||
//Parse comments
|
||||
post.comments.forEach(parseComment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a movie to find potential files to download
|
||||
*
|
||||
* @param {Object} info Information about the movie to parse
|
||||
*/
|
||||
var parseMovie = function(info){
|
||||
if(info.url != null)
|
||||
if(!files.includes(info.url))
|
||||
files.push(info.url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a conversation message to find potential files to download
|
||||
*
|
||||
* @param {Object} info Information about the movie to parse
|
||||
*/
|
||||
var parseConversationMessage = function(info){
|
||||
if(info.image_path != null)
|
||||
if(!files.includes(info.image_path))
|
||||
files.push(info.image_path);
|
||||
}
|
||||
|
||||
|
||||
//Main account information
|
||||
files.push(data.advanced_info.accountImage);
|
||||
files.push(data.advanced_info.backgroundImage);
|
||||
|
||||
//Posts
|
||||
data.posts.forEach(parsePost);
|
||||
|
||||
//Comments
|
||||
data.comments.forEach(parseComment);
|
||||
|
||||
//Movie
|
||||
data.movies.forEach(parseMovie);
|
||||
|
||||
//Conversation message
|
||||
//* All from users
|
||||
data.all_conversation_messages.forEach(parseConversationMessage);
|
||||
|
||||
//* All from conversations
|
||||
for (var num in data.conversations_messages) {
|
||||
if (data.conversations_messages.hasOwnProperty(num)) {
|
||||
var conversation = data.conversations_messages[num];
|
||||
conversation.forEach(parseConversationMessage);
|
||||
}
|
||||
}
|
||||
|
||||
//Related user information
|
||||
for (var key in data.users_info) {
|
||||
if (data.users_info.hasOwnProperty(key)) {
|
||||
parseUserInfo(data.users_info[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
}
|
@ -31,4 +31,135 @@ ComunicWeb.components.account.interface = {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether an email address is linked to an account or not
|
||||
*
|
||||
* @param {String} email The email address to check
|
||||
* @param {function} callback
|
||||
*/
|
||||
existsMail: function(email, callback){
|
||||
var apiURI = "account/exists_email";
|
||||
var params = {
|
||||
email: email
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether the security questions have been set for an account
|
||||
* with an email address or not
|
||||
*
|
||||
* @param {String} email The email address of the account
|
||||
* @param {function} callback
|
||||
*/
|
||||
checkSecurityQuestionsExistence: function(email, callback){
|
||||
var apiURI = "account/has_security_questions";
|
||||
var params = {
|
||||
email: email
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Given an email address, returns the security questions of a user
|
||||
*
|
||||
* @param {String} email The email address of the account
|
||||
* @param {function} callback
|
||||
*/
|
||||
getSecurityQuestions: function(email, callback){
|
||||
var apiURI = "account/get_security_questions";
|
||||
var params = {
|
||||
email: email
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get passowrd reset token using security answer
|
||||
*
|
||||
* @param {String} email The email address of the account
|
||||
* @param {Array} answers The answers to the security questions
|
||||
* @param {Function} callback
|
||||
*/
|
||||
resetPasswordWithSecurityAnswers: function(email, answers, callback){
|
||||
|
||||
//Prepare answers
|
||||
answersText = "";
|
||||
answers.forEach(function(answer){
|
||||
|
||||
if(answersText != "")
|
||||
answersText += "&";
|
||||
|
||||
answersText += encodeURIComponent(answer);
|
||||
|
||||
});
|
||||
|
||||
//Perform the request
|
||||
var apiURI = "account/check_security_answers";
|
||||
var params = {
|
||||
email: email,
|
||||
answers: answersText
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Check the validity of a reset password token
|
||||
*
|
||||
* @param {String} token The token to check
|
||||
* @param {Function} callback
|
||||
*/
|
||||
checkPasswordResetToken: function(token, callback){
|
||||
var apiURI = "account/check_password_reset_token";
|
||||
var params = {
|
||||
token: token
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, false, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset user password
|
||||
*
|
||||
* @param {String} token The token to check
|
||||
* @param {String} passwd The new password for the user
|
||||
* @param {Function} callback
|
||||
*/
|
||||
resetUserPassword: function(token, passwd, callback){
|
||||
var apiURI = "account/reset_user_passwd";
|
||||
var params = {
|
||||
token: token,
|
||||
password: passwd
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, false, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Request the export of all the data of the user
|
||||
*
|
||||
* @param {String} password The password of the user
|
||||
* @param {function} callback
|
||||
*/
|
||||
exportData: function(password, callback){
|
||||
var apiURI = "account/export_data";
|
||||
var params = {
|
||||
password: password
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Request the deletion of the account
|
||||
*
|
||||
* @param {string} password The password of the account
|
||||
* @param {function} callback
|
||||
*/
|
||||
deleteAccount: function(password, callback){
|
||||
var apiURI = "account/delete";
|
||||
var params = {
|
||||
password: password
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
}
|
@ -52,6 +52,18 @@ ComunicWeb.components.bottom.main = {
|
||||
langLink.onclick = function(){
|
||||
ComunicWeb.components.langPicker.show();
|
||||
};
|
||||
|
||||
add_space(leftElements);
|
||||
add_space(leftElements);
|
||||
|
||||
//Add about link
|
||||
var aboutLink = createElem2({
|
||||
appendTo: leftElements,
|
||||
type: "a",
|
||||
innerHTML: "<i class='fa fa-question-circle'></i> About",
|
||||
href: ComunicWeb.__config.aboutWebsiteURL
|
||||
});
|
||||
aboutLink.setAttribute("target", "_blank");
|
||||
}
|
||||
|
||||
}
|
@ -25,7 +25,7 @@ ComunicWeb.components.comments.actions = {
|
||||
|
||||
//Check for errors
|
||||
if(result.error){
|
||||
ComunicWeb.common.notificationSystem.showNotification("Couldn't get informations about a comment !", "danger");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("comments_actions_err_get_info_single"), "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ ComunicWeb.components.comments.editor = {
|
||||
|
||||
//Check for error
|
||||
if(result.error){
|
||||
ComunicWeb.common.notificationSystem.showNotification("An error occured while trying to update comment content !", "danger");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("comments_editor_err_update"), "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -39,8 +39,8 @@ ComunicWeb.components.comments.editor = {
|
||||
|
||||
//Prompt the user to enter the new content of the comment
|
||||
ComunicWeb.common.messages.inputString(
|
||||
"Edit comment content",
|
||||
"Please specify the new content of the comment: ",
|
||||
lang("comments_editor_title"),
|
||||
lang("comments_editor_notice"),
|
||||
infos.content,
|
||||
inputCallback
|
||||
);
|
||||
|
@ -46,9 +46,10 @@ ComunicWeb.components.comments.form = {
|
||||
type: "input",
|
||||
elemType: "text",
|
||||
class: "form-control",
|
||||
placeholder: "New comment...",
|
||||
placeholder: lang("comments_form_input_placeholder"),
|
||||
name: "content"
|
||||
});
|
||||
newCommentText.maxLength = 255;
|
||||
|
||||
|
||||
//Add button group
|
||||
@ -105,7 +106,7 @@ ComunicWeb.components.comments.form = {
|
||||
appendTo: buttonsGroup,
|
||||
type: "button",
|
||||
class: "btn btn-default btn-flat",
|
||||
innerHTML: "Send"
|
||||
innerHTML: lang("comments_form_send")
|
||||
});
|
||||
|
||||
//Catch form when submitted
|
||||
@ -116,15 +117,22 @@ ComunicWeb.components.comments.form = {
|
||||
|
||||
//Check the comment
|
||||
if(!hasImage && newCommentText.value < 5){
|
||||
ComunicWeb.common.notificationSystem.showNotification("Please type a valid comment! (at least 5 characters)", "danger");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("comments_form_err_invalid_comment"), "danger");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Lock send button
|
||||
sendButton.disabled = true;
|
||||
|
||||
//Try to create the comment
|
||||
var formData = new FormData(commentForm);
|
||||
//Prepare the request
|
||||
var formData = new FormData();
|
||||
formData.append("content", newCommentText.value);
|
||||
|
||||
//Check for image
|
||||
if(imageFile.files.length > 0)
|
||||
formData.append("image", imageFile.files[0], imageFile.files[0].name);
|
||||
|
||||
//Send the request
|
||||
ComunicWeb.components.comments.interface.create(postID, formData, function(result){
|
||||
|
||||
//Unlock send button
|
||||
@ -132,7 +140,7 @@ ComunicWeb.components.comments.form = {
|
||||
|
||||
//Check for errors
|
||||
if(result.error){
|
||||
ComunicWeb.common.notificationSystem.showNotification("Couldn't create comment! (check its content)", "danger");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("comments_form_err_create_comment"), "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ ComunicWeb.components.comments.ui = {
|
||||
|
||||
//Check for errors
|
||||
if(result.error){
|
||||
ComunicWeb.common.notificationSystem.showNotification("Couldn't informations about some users to display their comments !", "danger");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("comments_ui_err_get_users_info"), "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ ComunicWeb.components.comments.ui = {
|
||||
|
||||
//Check for errors
|
||||
if(result.error){
|
||||
ComunicWeb.common.notificationSystem.showNotification("Couldn't get informations about a user!", "danger");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("comments_ui_err_get_user_info"), "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ ComunicWeb.components.comments.ui = {
|
||||
createElem2({
|
||||
appendTo: rightContainer,
|
||||
type: "span",
|
||||
innerHTML: ComunicWeb.common.date.timeDiffToStr(infos.time_sent) + " ago"
|
||||
innerHTML: lang("dates_ago", [ComunicWeb.common.date.timeDiffToStr(infos.time_sent)])
|
||||
});
|
||||
|
||||
//Offer the user the possibility to delete and update the comment if he is allowed to do so
|
||||
@ -191,7 +191,7 @@ ComunicWeb.components.comments.ui = {
|
||||
//Make delete button lives
|
||||
deleteCommentLink.onclick = function(){
|
||||
|
||||
ComunicWeb.common.messages.confirm("Are you sure do you want to delete this comment ? This operation is unrecoverable!", function(response){
|
||||
ComunicWeb.common.messages.confirm(lang("comments_ui_confirm_delete"), function(response){
|
||||
|
||||
//Check if user cancelled the operation
|
||||
if(!response)
|
||||
@ -207,7 +207,7 @@ ComunicWeb.components.comments.ui = {
|
||||
|
||||
//Check for errors
|
||||
if(response.error){
|
||||
ComunicWeb.common.notificationSystem.showNotification("Could not delete comment!", "danger");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("comments_ui_err_delete_comment"), "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -385,6 +385,10 @@ ComunicWeb.components.conversations.chatWindows = {
|
||||
*/
|
||||
changeName: function(newName, infos){
|
||||
|
||||
//Reduce new name
|
||||
if(newName.length > 18)
|
||||
newName = newName.slice(0, 17) + "...";
|
||||
|
||||
//Empty name field
|
||||
emptyElem(infos.boxTitle);
|
||||
|
||||
|
@ -180,7 +180,7 @@ ComunicWeb.components.conversations.interface = {
|
||||
if(result.error){
|
||||
|
||||
//Log error
|
||||
ComunicWeb.debug.logMessage("Couldn't get informations about the conversation number "+conversationID+" !")
|
||||
ComunicWeb.debug.logMessage("Couldn't get informations about the conversation number "+conversationID+" !");
|
||||
|
||||
//Perform next action now
|
||||
nextStep(result);
|
||||
@ -343,6 +343,26 @@ ComunicWeb.components.conversations.interface = {
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the the lastest messages of a single conversation
|
||||
*
|
||||
* @param {Number} convID Target conversation ID
|
||||
* @param {Number} lastMessageID The ID of the last known message
|
||||
* @param {function} callback
|
||||
*/
|
||||
refreshSingleConversation: function(convID, lastMessageID, callback){
|
||||
|
||||
//Perform a request on the API
|
||||
var apiURI = "conversations/refresh_single";
|
||||
var params = {
|
||||
conversationID: convID,
|
||||
last_message_id: lastMessageID
|
||||
};
|
||||
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Empty conversations cache
|
||||
*
|
||||
|
@ -51,7 +51,7 @@ ComunicWeb.components.conversations.unreadDropdown = {
|
||||
appendTo: dropdownMenu,
|
||||
type: "li",
|
||||
class: "header",
|
||||
innerHTML: "Unread conversations"
|
||||
innerHTML: lang("conversations_dropdown_header")
|
||||
});
|
||||
|
||||
//Add conversations list
|
||||
@ -107,7 +107,7 @@ ComunicWeb.components.conversations.unreadDropdown = {
|
||||
//Check for errors
|
||||
if(conversations.error){
|
||||
//Display an error
|
||||
ComunicWeb.common.notificationSystem.showNotification("Could not retrieve the list of unread conversations !", "danger");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("conversations_dropdown_err_get_list"), "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ ComunicWeb.components.conversations.unreadDropdown = {
|
||||
//Check for errors
|
||||
if(usersInfos.error){
|
||||
//Display an error
|
||||
ComunicWeb.common.notificationSystem.showNotification("Could not get informations about some users !", "danger");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("conversations_dropdown_err_get_user_info"), "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ ComunicWeb.components.conversations.unreadDropdown = {
|
||||
appendTo: target,
|
||||
type: "p",
|
||||
class: "no-unread-conversation-msg",
|
||||
innerHTML: "You do not have any unread messages in the conversations you are following..."
|
||||
innerHTML: lang("conversations_dropdown_no_unread_notice")
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ ComunicWeb.components.friends.bar = {
|
||||
noFriendMessage.style.color = "#3c8dbc";
|
||||
noFriendMessage.style.fontSize = "150%";
|
||||
noFriendMessage.style.textAlign = "justify";
|
||||
noFriendMessage.innerHTML = "You have no friends yet! We can't display anything here for you for now... :("
|
||||
noFriendMessage.innerHTML = lang("friends_bar_no_friends_notice")
|
||||
}
|
||||
|
||||
//Enable slimscroll
|
||||
@ -159,7 +159,7 @@ ComunicWeb.components.friends.bar = {
|
||||
|
||||
//Make the link lives
|
||||
friendLink.onclick = function(){
|
||||
openUserPage(userIDorPath(userInfos));
|
||||
openUserPage(userInfos);
|
||||
|
||||
//For the responsive mode
|
||||
ComunicWeb.components.friends.bar.toggleShowHide();
|
||||
@ -276,9 +276,9 @@ ComunicWeb.components.friends.bar = {
|
||||
|
||||
//Change statusRow style
|
||||
if(accepted)
|
||||
statusRow.innerHTML = "Accepted";
|
||||
statusRow.innerHTML = lang("friends_bar_accepted");
|
||||
else
|
||||
statusRow.innerHTML = "Refused";
|
||||
statusRow.innerHTML = lang("friends_bar_rejected");
|
||||
|
||||
//Perform an API request
|
||||
ComunicWeb.components.friends.list.respondRequest(friendID, accepted);
|
||||
|
@ -213,7 +213,7 @@ ComunicWeb.components.friends.listModal = {
|
||||
userLink.onclick = function(){
|
||||
|
||||
//Open user page
|
||||
openUserPage(userIDorPath(users["user-" + id]));
|
||||
openUserPage(users["user-" + id]);
|
||||
|
||||
//Close all modals
|
||||
$(".modal").modal("hide");
|
||||
|
@ -55,7 +55,7 @@ ComunicWeb.components.friends.ui = {
|
||||
userLink.onclick = function(){
|
||||
|
||||
//Open user page
|
||||
openUserPage(userIDorPath(user));
|
||||
openUserPage(user);
|
||||
|
||||
//Close all modals
|
||||
$(".modal").modal("hide");
|
||||
|
113
assets/js/components/groups/info.js
Normal file
@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Groups information management
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
ComunicWeb.components.groups.info = {
|
||||
|
||||
/**
|
||||
* Group information cache
|
||||
*/
|
||||
_cache: {},
|
||||
|
||||
/**
|
||||
* Get information about a single group
|
||||
*
|
||||
* @param {Number} id The ID of the target group
|
||||
* @param {Function} callback
|
||||
*/
|
||||
getInfo: function(id, callback){
|
||||
|
||||
//First, check if the group is cached or not
|
||||
if(this._cache[id])
|
||||
return callback(this._cache[id]);
|
||||
|
||||
//Then query the server, if required
|
||||
ComunicWeb.components.groups.interface.getInfo(id, function(result){
|
||||
|
||||
//Check for errors
|
||||
if(result.error)
|
||||
return callback(result);
|
||||
|
||||
//Save group information
|
||||
ComunicWeb.components.groups.info._cache[id] = result;
|
||||
|
||||
//Call callback
|
||||
callback(result);
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Get information about a multiple groups
|
||||
*
|
||||
* @param {Array} list The list of the IDs of the group to get information about
|
||||
* @param {Function} callback
|
||||
*/
|
||||
getInfoMultiple: function(list, callback){
|
||||
|
||||
//First, check which group are unknown in the cache
|
||||
var toFetch = Array();
|
||||
|
||||
list.forEach(function(id){
|
||||
if(!ComunicWeb.components.groups.info._cache[id])
|
||||
toFetch.push(id);
|
||||
});
|
||||
|
||||
if(toFetch.length == 0){
|
||||
this.getInfoMultiplePreCallback(list, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
//Perform the request over the server
|
||||
ComunicWeb.components.groups.interface.getInfoMultiple(toFetch, function(result){
|
||||
|
||||
//Check for errors
|
||||
if(result.error)
|
||||
return notify("Could not get information about the groups!", "danger");
|
||||
|
||||
//Process the list of groups
|
||||
for(i in result){
|
||||
|
||||
//Save group information in the cache
|
||||
ComunicWeb.components.groups.info._cache[result[i].id] = result[i];
|
||||
|
||||
}
|
||||
|
||||
//Call callback
|
||||
ComunicWeb.components.groups.info.getInfoMultiplePreCallback(list, callback);
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Get multiple information pre-callback
|
||||
*
|
||||
* @param {Array} list The list of the IDs of teh group to get information about
|
||||
* @param {Function} callback
|
||||
*/
|
||||
getInfoMultiplePreCallback: function(list, callback){
|
||||
|
||||
var groupInfo = {};
|
||||
|
||||
list.forEach(function(id){
|
||||
groupInfo[id] = ComunicWeb.components.groups.info._cache[id];
|
||||
});
|
||||
|
||||
//Call callback
|
||||
callback(groupInfo);
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear cache
|
||||
*/
|
||||
clearCache: function(){
|
||||
this._cache = {};
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
//Register cache cleaner
|
||||
ComunicWeb.common.cacheManager.registerCacheCleaner("ComunicWeb.components.groups.info.clearCache");
|
341
assets/js/components/groups/interface.js
Normal file
@ -0,0 +1,341 @@
|
||||
/**
|
||||
* Groups API interface
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
ComunicWeb.components.groups.interface = {
|
||||
|
||||
/**
|
||||
* Create a group
|
||||
*
|
||||
* @param {String} name The name of the group to create
|
||||
* @param {Function} callback
|
||||
*/
|
||||
create: function(name, callback){
|
||||
|
||||
//Perform a request over the API
|
||||
var apiURI = "groups/create";
|
||||
var params = {
|
||||
name: name
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the list of groups of the user
|
||||
*
|
||||
* @param {Function} callback
|
||||
*/
|
||||
getListUser: function(callback){
|
||||
//Perform a request over the API
|
||||
var apiURI = "groups/get_my_list";
|
||||
var params = {};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a user membership
|
||||
*
|
||||
* @param {Number} groupID The ID of the target group
|
||||
* @param {Function} callback
|
||||
*/
|
||||
removeMembership: function(groupID, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/remove_membership";
|
||||
var params = {
|
||||
id: groupID
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get information about a group
|
||||
*
|
||||
* @param {Number} id The ID of the target group
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
getInfo: function(id, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/get_info";
|
||||
var params = {
|
||||
id: id
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get information about multiple groups
|
||||
*
|
||||
* @param {Array} list The IDs of the groups to get
|
||||
* @param {Function} callback
|
||||
*/
|
||||
getInfoMultiple: function(list, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/get_multiple_info";
|
||||
var params = {
|
||||
list: list
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get advanced information about a group
|
||||
*
|
||||
* @param {Number} id The ID of the target group
|
||||
* @param {Function} callback Callback
|
||||
*/
|
||||
getAdvancedInfo: function(id, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/get_advanced_info";
|
||||
var params = {
|
||||
id: id
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the settings of a group
|
||||
*
|
||||
* @param {Number} id The ID of the target group
|
||||
* @param {Function} callback
|
||||
*/
|
||||
getSettings: function(id, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/get_settings";
|
||||
var params = {
|
||||
id: id
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set (update) the settings of a group
|
||||
*
|
||||
* @param {Number} id The ID of the target group
|
||||
* @param {Object} settings The new settings to apply to
|
||||
* the group
|
||||
* @param {Function} callback
|
||||
*/
|
||||
setSettings: function(id, settings, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/set_settings";
|
||||
settings.id = id;
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, settings, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Check the availability of a virtual directory for a group
|
||||
*
|
||||
* @param {String} directory The directory to check
|
||||
* @param {Number} groupID The ID of the group to check
|
||||
* @param {Function} callback
|
||||
*/
|
||||
checkVirtualDirectory: function(directory, groupID, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/checkVirtualDirectory";
|
||||
var params = {
|
||||
groupID: groupID,
|
||||
directory: directory
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Upload a new group logo
|
||||
*
|
||||
* @param {Number} id The ID of the target group
|
||||
* @param {FormData} data The form data that contains the
|
||||
* new logo (parameter name : logo)
|
||||
* @param {Function} callback
|
||||
*/
|
||||
uploadLogo: function(id, data, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/upload_logo";
|
||||
data.append("id", id);
|
||||
ComunicWeb.common.api.makeFormDatarequest(apiURI, data, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete user logo
|
||||
*
|
||||
* @param {Number} id The ID of the target group
|
||||
* @param {Function} callback
|
||||
*/
|
||||
deleteLogo: function(id, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/delete_logo";
|
||||
var params = {
|
||||
id: id
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Respond to a group invitation
|
||||
*
|
||||
* @param {Number} id The ID of the target group
|
||||
* @param {Boolean} accept Specify whether the invitation was
|
||||
* accepted or not
|
||||
* @param {Function} callback
|
||||
*/
|
||||
respondInvitation: function(id, accept, callback) {
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/respond_invitation";
|
||||
var params = {
|
||||
id: id,
|
||||
accept: accept
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Cancel a membership request
|
||||
*
|
||||
* @param {Number} id The ID of the target group
|
||||
* @param {Function} callback
|
||||
*/
|
||||
cancelRequest: function(id, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/cancel_request";
|
||||
var params = {
|
||||
id: id
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Send a request to join a group
|
||||
*
|
||||
* @param {Number} id The ID of the target group
|
||||
* @param {Function} callback
|
||||
*/
|
||||
sendRequest: function(id, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/send_request";
|
||||
var params = {
|
||||
id: id
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the members of a group
|
||||
*
|
||||
* @param {Number} id The ID of the target group
|
||||
* @param {Function} callback
|
||||
*/
|
||||
getMembers: function(id, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/get_members";
|
||||
var params = {
|
||||
id: id
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get information about a single user membership
|
||||
*
|
||||
* @param {Number} userID The ID of the target user
|
||||
* @param {Number} groupID The ID of the target group
|
||||
* @param {Function} callback The result
|
||||
*/
|
||||
getMembership: function(userID, groupID, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/get_membership";
|
||||
var params = {
|
||||
groupID: groupID,
|
||||
userID: userID
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove (delete) a member from the group
|
||||
*
|
||||
* @param {Number} groupID The ID of the target group
|
||||
* @param {Number} userID The ID of the target user
|
||||
* @param {Function} callback
|
||||
*/
|
||||
deleteMember: function(groupID, userID, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/delete_member";
|
||||
var params = {
|
||||
groupID: groupID,
|
||||
userID: userID
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Respond to a membership request
|
||||
*
|
||||
* @param {Number} groupID The ID of the target group
|
||||
* @param {Number} userID The ID of the target user
|
||||
* @param {Boolean} accept Specify whether the request is accepted or not
|
||||
*/
|
||||
respondRequest: function(groupID, userID, accept, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/respond_request";
|
||||
var params = {
|
||||
groupID: groupID,
|
||||
userID: userID,
|
||||
accept: accept
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Cancel a membership invitation
|
||||
*
|
||||
* @param {Number} groupID The ID of the target group
|
||||
* @param {Number} userID The ID of the target user
|
||||
* @param {Function} callback
|
||||
*/
|
||||
cancelInvitation: function(groupID, userID, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/cancel_invitation";
|
||||
var params = {
|
||||
groupID: groupID,
|
||||
userID: userID
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the membership of a user
|
||||
*
|
||||
* @param {Number} groupID The ID of the target group
|
||||
* @param {Number} userID The ID of the target user
|
||||
* @param {String} level The new membership level for the user
|
||||
* @param {Function} callback
|
||||
*/
|
||||
updateMembership: function(groupID, userID, level, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/update_membership_level";
|
||||
var params = {
|
||||
groupID: groupID,
|
||||
userID: userID,
|
||||
level: level
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set whether a user is following a group or not
|
||||
*
|
||||
* @param {Number} groupID The ID of the target group
|
||||
* @param {Boolean} follow
|
||||
* @param {Function} callback
|
||||
*/
|
||||
setFollowing: function(groupID, follow, callback){
|
||||
//Perform the request over the API
|
||||
var apiURI = "groups/set_following";
|
||||
var params = {
|
||||
groupID: groupID,
|
||||
follow: follow
|
||||
};
|
||||
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
|
||||
}
|
||||
};
|
61
assets/js/components/groups/utils.js
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Groups utilities
|
||||
*
|
||||
* @author Pierre HUBERT
|
||||
*/
|
||||
|
||||
ComunicWeb.components.groups.utils = {
|
||||
|
||||
/**
|
||||
* Extract users ids from members list
|
||||
*
|
||||
* @param {Array} list The list of members to process
|
||||
* @return {Array} The list of the IDs of the members of group
|
||||
*/
|
||||
getMembersIDs: function(list){
|
||||
|
||||
var IDs = [];
|
||||
|
||||
//Process the list of IDs
|
||||
list.forEach(function(member){
|
||||
IDs.push(member.user_id);
|
||||
});
|
||||
|
||||
return IDs;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether a user is a member (or more) of a group or not
|
||||
*
|
||||
* @param {Object} info Information about the target group
|
||||
* @return {boolean} TRUE if the user is a member of the group
|
||||
* FALSE else
|
||||
*/
|
||||
isGroupMember: function(info){
|
||||
return info.membership == "member"
|
||||
|| info.membership == "moderator"
|
||||
|| info.membership == "administrator";
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether a user can create posts for a group or not
|
||||
*
|
||||
* @param {Object} info Information about the target group
|
||||
* @return {boolean} TRUE if the user can create a post / FALSE else
|
||||
*/
|
||||
canCreatePosts: function(info){
|
||||
|
||||
//Administrator and moderators can always create posts
|
||||
if(info.membership == "administrator" || info.membership == "moderator")
|
||||
return true;
|
||||
|
||||
if(info.membership == "member" && info.posts_level == "members")
|
||||
return true;
|
||||
|
||||
//In all the other case, the user can not create posts
|
||||
return false;
|
||||
|
||||
},
|
||||
|
||||
}
|
@ -36,14 +36,14 @@ ComunicWeb.components.langPicker = {
|
||||
class: "modal-header"
|
||||
});
|
||||
|
||||
var closeModal = createElem2({
|
||||
var closeModalBtn = createElem2({
|
||||
appendTo: modalHeader,
|
||||
type: "button",
|
||||
class: "close",
|
||||
});
|
||||
|
||||
createElem2({
|
||||
appendTo: closeModal,
|
||||
appendTo: closeModalBtn,
|
||||
type: "span",
|
||||
innerHTML: "x"
|
||||
});
|
||||
@ -62,27 +62,27 @@ ComunicWeb.components.langPicker = {
|
||||
class: "modal-body",
|
||||
});
|
||||
|
||||
//Display the list of languages
|
||||
var langs = [
|
||||
["fr", "Français"],
|
||||
["en", "English"]
|
||||
];
|
||||
|
||||
//Display the list of language
|
||||
var buttons = [];
|
||||
langs.forEach(function(lang){
|
||||
for(language in ComunicWeb.common.langs.list){
|
||||
|
||||
if(typeof language !== "string")
|
||||
continue;
|
||||
|
||||
var info = ComunicWeb.common.langs.list[language];
|
||||
|
||||
const button = createElem2({
|
||||
appendTo: modalBody,
|
||||
type: "div",
|
||||
class: "btn btn-default",
|
||||
innerHTML: lang[1]
|
||||
innerHTML: info.local_name + " (" + info.name + ")"
|
||||
});
|
||||
button.setAttribute("data-lang", lang[0]);
|
||||
button.setAttribute("data-lang", language);
|
||||
buttons.push(button);
|
||||
|
||||
add_space(modalBody);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
//Modal footer
|
||||
var modalFooter = createElem2({
|
||||
@ -113,7 +113,12 @@ ComunicWeb.components.langPicker = {
|
||||
closeModal();
|
||||
|
||||
//Set the language
|
||||
ComunicWeb.common.langs.setLang(this.getAttribute("data-lang"));
|
||||
var lang = this.getAttribute("data-lang");
|
||||
ComunicWeb.common.langs.setLang(lang);
|
||||
|
||||
//Save settings in user account if signed in
|
||||
if(signed_in())
|
||||
ComunicWeb.components.settings.interface.setLanguage(lang);
|
||||
|
||||
//Restart the app
|
||||
ComunicWeb.common.system.reset();
|
||||
@ -122,7 +127,7 @@ ComunicWeb.components.langPicker = {
|
||||
|
||||
//Make the buttons live
|
||||
cancelButton.onclick = closeModal;
|
||||
closeModal.onclick = closeModal;
|
||||
closeModalBtn.onclick = closeModal;
|
||||
|
||||
//Show the modal
|
||||
$(modal).modal('show');
|
||||
|
@ -57,10 +57,10 @@ ComunicWeb.components.like.button = {
|
||||
else {
|
||||
//Update message
|
||||
if(count == 1){
|
||||
likeMsg.innerHTML = "1 like";
|
||||
likeMsg.innerHTML = lang("like_btn_one_like");
|
||||
}
|
||||
else
|
||||
likeMsg.innerHTML = count + " likes";
|
||||
likeMsg.innerHTML = lang("like_btn_x_likes", [count]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -69,10 +69,10 @@ ComunicWeb.components.like.button = {
|
||||
|
||||
//Update the message
|
||||
if(liking == true){
|
||||
likeMsg.innerHTML = "Liking"
|
||||
likeMsg.innerHTML = lang("like_btn_liking")
|
||||
}
|
||||
else {
|
||||
likeMsg.innerHTML = "Like";
|
||||
likeMsg.innerHTML = lang("like_btn_like");
|
||||
}
|
||||
|
||||
//Add total count if possible
|
||||
|
@ -32,6 +32,9 @@ ComunicWeb.components.menuBar.authenticated = {
|
||||
//Add user name
|
||||
this.addUserName(navbarRightElemList);
|
||||
|
||||
//Alternate latest posts button
|
||||
this.addAlternateLatestPostsButton(navbarRightElemList);
|
||||
|
||||
//Add friends list button
|
||||
this.addFriendListButton(navbarRightElemList);
|
||||
|
||||
@ -75,6 +78,35 @@ ComunicWeb.components.menuBar.authenticated = {
|
||||
dropdownContent.className = "dropdown-menu"
|
||||
dropdownContent.setAttribute("role", "menu");
|
||||
|
||||
|
||||
//Add conversations link
|
||||
var conversationsButton = createElem2({
|
||||
appendTo: dropdownContent,
|
||||
type: "li"
|
||||
});
|
||||
var conversationsLink = createElem2({
|
||||
appendTo: conversationsButton,
|
||||
type: "a",
|
||||
innerLang: "menu_bar_action_conversations"
|
||||
});
|
||||
conversationsButton.onclick = function(){
|
||||
openPage("conversations");
|
||||
};
|
||||
|
||||
//Add groups link
|
||||
var groupsButton = createElem2({
|
||||
appendTo: dropdownContent,
|
||||
type: "li"
|
||||
});
|
||||
createElem2({
|
||||
appendTo: groupsButton,
|
||||
type: "a",
|
||||
innerLang: "menu_bar_action_groups"
|
||||
});
|
||||
groupsButton.onclick = function(){
|
||||
openPage("groups");
|
||||
}
|
||||
|
||||
//Add settings link
|
||||
var settingsButton = createElem2({
|
||||
appendTo: dropdownContent,
|
||||
@ -83,7 +115,7 @@ ComunicWeb.components.menuBar.authenticated = {
|
||||
var settingsLink = createElem2({
|
||||
appendTo: settingsButton,
|
||||
type: "a",
|
||||
innerHTML: "Settings"
|
||||
innerLang: "menu_bar_action_settings"
|
||||
});
|
||||
settingsButton.onclick = function(){
|
||||
openPage("settings");
|
||||
@ -99,6 +131,34 @@ ComunicWeb.components.menuBar.authenticated = {
|
||||
return dropdownContent;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add alternate latest posts button
|
||||
* (if the screen is too small to display "Comunic")
|
||||
*
|
||||
* @param {HTMLElement} target The target for the ubutton
|
||||
*/
|
||||
addAlternateLatestPostsButton: function(target){
|
||||
//Create button
|
||||
var button = createElem2({
|
||||
type: "li",
|
||||
appendTo: target,
|
||||
class: "alternate-latest-posts-button"
|
||||
});
|
||||
|
||||
//Create link
|
||||
var link = createElem("a", button);
|
||||
createElem2({
|
||||
type: "i",
|
||||
appendTo: link,
|
||||
class: "fa fa-history"
|
||||
});
|
||||
|
||||
//Makes link lives
|
||||
link.addEventListener("click", function(){
|
||||
openPage("latest");
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Add friendsList toggle button
|
||||
*
|
||||
@ -157,7 +217,7 @@ ComunicWeb.components.menuBar.authenticated = {
|
||||
userimage.src = userInfos.accountImage;
|
||||
|
||||
userlinkelement.onclick = function(){
|
||||
openUserPage(userIDorPath(userInfos));
|
||||
openUserPage(userInfos);
|
||||
}
|
||||
|
||||
}), true);
|
||||
@ -170,9 +230,10 @@ ComunicWeb.components.menuBar.authenticated = {
|
||||
* @return {HTMLElement} The user element
|
||||
*/
|
||||
addSearchForm: function(navbarElem){
|
||||
//Create form element
|
||||
|
||||
//Create form element (large screens)
|
||||
var searchForm = createElem("li", navbarElem);
|
||||
searchForm.className = "dropdown navbar-form navbar-left messages-menu";
|
||||
searchForm.className = "dropdown navbar-form navbar-left messages-menu hidden-xs";
|
||||
searchForm.setAttribute("role", "search");
|
||||
|
||||
//Create form group
|
||||
@ -191,6 +252,24 @@ ComunicWeb.components.menuBar.authenticated = {
|
||||
dropdownContainer.className = "dropdown-menu";
|
||||
|
||||
//Initializate menu
|
||||
ComunicWeb.components.searchForm.init(searchInput, dropdownContainer);
|
||||
ComunicWeb.components.search.form.init(searchInput, dropdownContainer);
|
||||
|
||||
//Create search link (small screen)
|
||||
var searchLinkLi = createElem2({
|
||||
appendTo: navbarElem,
|
||||
type: "li",
|
||||
class: "navbar-left messages-menu visible-xs"
|
||||
});
|
||||
|
||||
var searchLink = createElem2({
|
||||
appendTo: searchLinkLi,
|
||||
type: "a",
|
||||
innerHTML: "Search"
|
||||
});
|
||||
|
||||
searchLink.addEventListener("click", function(){
|
||||
openPage("search");
|
||||
});
|
||||
|
||||
}
|
||||
};
|
@ -91,14 +91,12 @@ ComunicWeb.components.menuBar.common = {
|
||||
var navbarCollapsIcon = createElem("i", navbarCollapsedButton);
|
||||
navbarCollapsIcon.className = "fa fa-bars";
|
||||
|
||||
//Now we need to know if user is logged in or not
|
||||
var userLoggedIn = ComunicWeb.user.userLogin.getUserLoginState();
|
||||
|
||||
//Save login information in menubar before continuing
|
||||
menuContainer.setAttribute("forActiveUser", userLoggedIn);
|
||||
menuContainer.setAttribute("forActiveUser", signed_in());
|
||||
|
||||
//Call specific menu
|
||||
if(userLoggedIn){
|
||||
if(signed_in()){
|
||||
//Call authenticated menubar
|
||||
ComunicWeb.components.menuBar.authenticated.addElements(containerElem);
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ ComunicWeb.components.notifications.dropdown = {
|
||||
appendTo: dropdownMenu,
|
||||
type: "li",
|
||||
class: "header",
|
||||
innerHTML: "Notifications"
|
||||
innerHTML: lang("notifications_dropdown_title")
|
||||
});
|
||||
|
||||
//Add notifications list
|
||||
@ -93,13 +93,13 @@ ComunicWeb.components.notifications.dropdown = {
|
||||
var deleteAllLink = createElem2({
|
||||
appendTo: dropdownBottom,
|
||||
type: "a",
|
||||
innerHTML: "Delete all"
|
||||
innerHTML: lang("notifications_dropdown_delete_all_link")
|
||||
});
|
||||
|
||||
//Make the delete all notifications link lives
|
||||
deleteAllLink.onclick = function(){
|
||||
|
||||
ComunicWeb.common.messages.confirm("Are you sure do you want to delete all the notifications ? This operation can not be cancelled !", function(accept){
|
||||
ComunicWeb.common.messages.confirm(lang("notifications_dropdown_confirm_delete_all"), function(accept){
|
||||
|
||||
//We continue only if the user confirmed the operation
|
||||
if(!accept)
|
||||
@ -110,12 +110,12 @@ ComunicWeb.components.notifications.dropdown = {
|
||||
|
||||
//Check for errors
|
||||
if(result.error){
|
||||
ComunicWeb.common.notificationSystem.showNotification("An error occured while trying to delete all the notifications !", "danger");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("notifications_dropdown_err_delete_all_notifications"), "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
//Display success
|
||||
ComunicWeb.common.notificationSystem.showNotification("The entire list of notification has been cleared.", "success");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("notifications_dropdown_delete_all_success"), "success");
|
||||
|
||||
});
|
||||
|
||||
@ -150,7 +150,7 @@ ComunicWeb.components.notifications.dropdown = {
|
||||
|
||||
//Check for errors
|
||||
if(result.error){
|
||||
ComunicWeb.common.notificationSystem.showNotification("An error occured while trying to retrieve notifications list !", "danger");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("notifications_dropdown_err_get_notifs_list"), "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -162,10 +162,17 @@ ComunicWeb.components.notifications.dropdown = {
|
||||
|
||||
//Check for errors
|
||||
if(users.error){
|
||||
ComunicWeb.common.notificationSystem.showNotification("An error occured while trying to retrieve users informations for the notifications !", "danger");
|
||||
ComunicWeb.common.notificationSystem.showNotification(lang("notifications_dropdown_err_get_related_users_info"), "danger");
|
||||
return;
|
||||
}
|
||||
|
||||
//Get information about the groups
|
||||
var groups_id = ComunicWeb.components.notifications.utils.get_groups_id(result);
|
||||
getInfoMultipleGroups(groups_id, function(groups){
|
||||
|
||||
//Check for errors
|
||||
if(groups.error)
|
||||
return notify(lang("notifications_dropdown_err_get_related_groups_info"), "danger");
|
||||
|
||||
//Empty the target list
|
||||
list.innerHTML = "";
|
||||
@ -175,16 +182,19 @@ ComunicWeb.components.notifications.dropdown = {
|
||||
const notification = result[i];
|
||||
|
||||
//Display the notification
|
||||
ComunicWeb.components.notifications.ui.display_notification(notification, list, users);
|
||||
ComunicWeb.components.notifications.ui.display_notification(notification, list, users, groups);
|
||||
}
|
||||
|
||||
//Display a message if there isn't any notification to display
|
||||
if(result.length == 0){
|
||||
|
||||
list.innerHTML = "<li class='no-notification-msg'>You do not have any notification yet.</li>";
|
||||
list.innerHTML = "<li class='no-notification-msg'>" + lang("notifications_dropdown_no_notif_notice") + "</li>";
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
}, false);
|
||||
|
||||
|
||||
|
@ -13,8 +13,9 @@ ComunicWeb.components.notifications.ui = {
|
||||
* @param {HTMLElement} target The target of the notification
|
||||
* @param {Object} users Informations about users that might be required
|
||||
* to display the notification
|
||||
* @param {Object} groups Information about the potential related groups
|
||||
*/
|
||||
display_notification: function(data, target, users){
|
||||
display_notification: function(data, target, users, groups){
|
||||
|
||||
//Generate the informations about the notifications
|
||||
var from_user = users["user-"+data.from_user_id];
|
||||
@ -37,6 +38,20 @@ ComunicWeb.components.notifications.ui = {
|
||||
if(data.type == "rejected_friend_request")
|
||||
message += "rejected your friendship request.";
|
||||
|
||||
//About group membership
|
||||
if(data.type == "sent_group_membership_invitation")
|
||||
message += "invited you to join the group";
|
||||
if(data.type == "accepted_group_membership_invitation")
|
||||
message += "accepted his invitation to join the group";
|
||||
if(data.type == "rejected_group_membership_invitation")
|
||||
message += "rejected his invitation to join the group";
|
||||
if(data.type == "sent_group_membership_request")
|
||||
message += "sent a request to join the group";
|
||||
if(data.type == "accepted_group_membership_request")
|
||||
message += "accepted your request to join the group";
|
||||
if(data.type == "rejected_group_membership_request")
|
||||
message += "rejected your request to join the group";
|
||||
|
||||
//Generic element creation
|
||||
if(data.type == "elem_created"){
|
||||
|
||||
@ -49,6 +64,7 @@ ComunicWeb.components.notifications.ui = {
|
||||
message += " ";
|
||||
|
||||
//Notification target
|
||||
//User page
|
||||
if(data.from_container_type == "user_page"){
|
||||
|
||||
if(data.from_user_id == data.from_container_id)
|
||||
@ -58,6 +74,15 @@ ComunicWeb.components.notifications.ui = {
|
||||
|
||||
}
|
||||
|
||||
//Group page
|
||||
if(data.from_container_type == "group_page"){
|
||||
message += "on the group "+groups[data.from_container_id].name+".";
|
||||
}
|
||||
|
||||
//Group membership
|
||||
if(data.on_elem_type == "group_membership")
|
||||
message += groups[data.on_elem_id].name;
|
||||
|
||||
//Create notification action
|
||||
var action = function(){
|
||||
|
||||
@ -77,7 +102,18 @@ ComunicWeb.components.notifications.ui = {
|
||||
if(data.on_elem_type == "friend_request"){
|
||||
|
||||
//Open user page
|
||||
openUserPage(data.from_user_id);
|
||||
openUserPageFromID(data.from_user_id);
|
||||
|
||||
}
|
||||
|
||||
//For the group membership
|
||||
if(data.on_elem_type == "group_membership"){
|
||||
|
||||
//Open appropriate page
|
||||
if(data.type == "sent_group_membership_request")
|
||||
openPage("groups/"+data.on_elem_id+"/members");
|
||||
else
|
||||
openGroupPage(groups[data.on_elem_id]);
|
||||
|
||||
}
|
||||
|
||||
|