diff --git a/frappe/core/doctype/user/user.json b/frappe/core/doctype/user/user.json
index c7dcf918aa..59ca2849a3 100644
--- a/frappe/core/doctype/user/user.json
+++ b/frappe/core/doctype/user/user.json
@@ -435,6 +435,28 @@
"set_only_once": 0,
"unique": 0
},
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "fieldname": "mute_sounds",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Mute Sounds",
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
{
"allow_on_submit": 0,
"bold": 0,
@@ -1228,7 +1250,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 5,
- "modified": "2015-10-29 07:52:54.705196",
+ "modified": "2015-11-03 09:57:27.930248",
"modified_by": "Administrator",
"module": "Core",
"name": "User",
diff --git a/frappe/hooks.py b/frappe/hooks.py
index 7d543e711f..74a7c0f319 100644
--- a/frappe/hooks.py
+++ b/frappe/hooks.py
@@ -165,3 +165,14 @@ default_background = "/assets/frappe/images/ui/into-the-dawn.jpg"
get_translated_dict = {
("doctype", "System Settings"): "frappe.geo.country_info.get_translated_dict"
}
+
+sounds = [
+ {"name": "email", "src": "/assets/frappe/sounds/email.mp3"},
+ {"name": "submit", "src": "/assets/frappe/sounds/submit.mp3"},
+ {"name": "cancel", "src": "/assets/frappe/sounds/cancel.mp3"},
+ {"name": "delete", "src": "/assets/frappe/sounds/delete.mp3"},
+ {"name": "click", "src": "/assets/frappe/sounds/click.mp3"},
+ {"name": "error", "src": "/assets/frappe/sounds/error.mp3"},
+ # {"name": "alert", "src": "/assets/frappe/sounds/alert.mp3"},
+ # {"name": "chime", "src": "/assets/frappe/sounds/chime.mp3"},
+]
diff --git a/frappe/public/js/frappe/form/footer/timeline.js b/frappe/public/js/frappe/form/footer/timeline.js
index 250b88c9b2..dc70a410da 100644
--- a/frappe/public/js/frappe/form/footer/timeline.js
+++ b/frappe/public/js/frappe/form/footer/timeline.js
@@ -230,6 +230,8 @@ frappe.ui.form.Comments = Class.extend({
if(!r.exc) {
me.input.val("");
+ frappe.utils.play_sound("click");
+
var comment = r.message;
var comments = me.get_comments();
var comment_exists = false;
@@ -261,6 +263,8 @@ frappe.ui.form.Comments = Class.extend({
},
callback: function(r) {
if(!r.exc) {
+ frappe.utils.play_sound("delete");
+
me.frm.get_docinfo().comments =
$.map(me.frm.get_docinfo().comments,
function(v) {
diff --git a/frappe/public/js/frappe/list/doclistview.js b/frappe/public/js/frappe/list/doclistview.js
index bdec7e3e78..b17b0aa363 100644
--- a/frappe/public/js/frappe/list/doclistview.js
+++ b/frappe/public/js/frappe/list/doclistview.js
@@ -421,16 +421,16 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
})
}, true);
}
-
+
//bulk assignment
me.page.add_menu_item(__("Assign To"), function(){
-
+
docname = [];
-
+
$.each(me.get_checked_items(), function(i, doc){
docname.push(doc.name);
})
-
+
if(docname.length >= 1){
me.dialog = frappe.ui.to_do_dialog({
obj: me,
@@ -439,7 +439,7 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
docname: docname,
bulk_assign: true,
re_assign: true,
- callback: function(){
+ callback: function(){
me.dirty = true;
me.refresh();
}
@@ -544,6 +544,7 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
doctype: me.doctype
},
callback: function() {
+ frappe.utils.play_sound("delete");
me.set_working(false);
me.dirty = true;
me.refresh();
diff --git a/frappe/public/js/frappe/misc/utils.js b/frappe/public/js/frappe/misc/utils.js
index 9fad0213be..17db281cf5 100644
--- a/frappe/public/js/frappe/misc/utils.js
+++ b/frappe/public/js/frappe/misc/utils.js
@@ -493,5 +493,22 @@ frappe.utils = {
is_image_file: function(filename) {
return (/\.(gif|jpg|jpeg|tiff|png|svg)$/i).test(filename);
+ },
+
+ play_sound: function(name) {
+ try {
+ if (frappe.boot.user.mute_sounds) {
+ return;
+ }
+
+ var audio = $("#sound-" + name)[0];
+ audio.volume = audio.getAttribute("volume");
+ audio.play();
+
+ } catch(e) {
+ console.log("Cannot play sound", name, e);
+ // pass
+ }
+
}
};
diff --git a/frappe/public/js/frappe/model/model.js b/frappe/public/js/frappe/model/model.js
index 67e0d87c9f..e32439df20 100644
--- a/frappe/public/js/frappe/model/model.js
+++ b/frappe/public/js/frappe/model/model.js
@@ -472,6 +472,7 @@ $.extend(frappe.model, {
},
callback: function(r, rt) {
if(!r.exc) {
+ frappe.utils.play_sound("delete");
frappe.model.clear_doc(doctype, docname);
if(callback) callback(r,rt);
}
diff --git a/frappe/public/js/frappe/request.js b/frappe/public/js/frappe/request.js
index 59a1a52666..5cf0a0a583 100644
--- a/frappe/public/js/frappe/request.js
+++ b/frappe/public/js/frappe/request.js
@@ -84,14 +84,16 @@ frappe.request.call = function(opts) {
}
}
+ frappe.utils.play_sound("error");
msgprint(__("Not permitted"));
},
508: function(xhr) {
+ frappe.utils.play_sound("error");
msgprint(__("Another transaction is blocking this one. Please try again in a few seconds."));
},
413: function(data, xhr) {
msgprint(__("File size exceeded the maximum allowed size of {0} MB",
- [(frappe.boot.max_file_size || 5242880) / 1048576]))
+ [(frappe.boot.max_file_size || 5242880) / 1048576]));
},
417: function(xhr) {
var r = xhr.responseJSON;
@@ -102,6 +104,7 @@ frappe.request.call = function(opts) {
r = xhr.responseText;
}
}
+
opts.error_callback && opts.error_callback(r);
},
501: function(data, xhr) {
@@ -109,6 +112,7 @@ frappe.request.call = function(opts) {
opts.error_callback && opts.error_callback(data, xhr.responseText);
},
500: function(xhr) {
+ frappe.utils.play_sound("error");
msgprint(__("Server Error: Please check your server logs or contact tech support."))
opts.error_callback && opts.error_callback();
frappe.request.report_error(xhr, opts);
diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js
index 4167fdbdac..33a43818bb 100644
--- a/frappe/public/js/frappe/views/communication.js
+++ b/frappe/public/js/frappe/views/communication.js
@@ -434,6 +434,8 @@ frappe.views.CommunicationComposer = Class.extend({
btn: btn,
callback: function(r) {
if(!r.exc) {
+ frappe.utils.play_sound("email");
+
if(form_values.send_email && r.message["emails_not_sent_to"]) {
msgprint( __("Email not sent to {0} (unsubscribed / disabled)",
[ frappe.utils.escape_html(r.message["emails_not_sent_to"]) ]) );
diff --git a/frappe/public/js/legacy/form.js b/frappe/public/js/legacy/form.js
index db3ab56feb..86a0ee8f86 100644
--- a/frappe/public/js/legacy/form.js
+++ b/frappe/public/js/legacy/form.js
@@ -635,6 +635,10 @@ _f.Frm.prototype._save = function(save_action, callback, btn, on_error) {
var after_save = function(r) {
if(!r.exc) {
+ if (["Save", "Update", "Amend"].indexOf(save_action)!==-1) {
+ frappe.utils.play_sound("click");
+ }
+
me.script_manager.trigger("after_save");
me.refresh();
} else {
@@ -691,6 +695,7 @@ _f.Frm.prototype.savesubmit = function(btn, callback, on_error) {
me.save('Submit', function(r) {
if(!r.exc) {
+ frappe.utils.play_sound("submit");
callback && callback();
me.script_manager.trigger("on_submit");
}
@@ -713,6 +718,7 @@ _f.Frm.prototype.savecancel = function(btn, callback, on_error) {
var after_cancel = function(r) {
if(!r.exc) {
+ frappe.utils.play_sound("cancel");
me.refresh();
callback && callback();
me.script_manager.trigger("after_cancel");
@@ -746,6 +752,7 @@ _f.Frm.prototype.amend_doc = function() {
newdoc.amendment_date = dateutil.obj_to_str(new Date());
}
this.copy_doc(fn, 1);
+ frappe.utils.play_sound("click");
}
_f.Frm.prototype.disable_save = function() {
diff --git a/frappe/public/sounds/alert.mp3 b/frappe/public/sounds/alert.mp3
new file mode 100644
index 0000000000..7a676a1a8a
Binary files /dev/null and b/frappe/public/sounds/alert.mp3 differ
diff --git a/frappe/public/sounds/cancel.mp3 b/frappe/public/sounds/cancel.mp3
new file mode 100644
index 0000000000..3a4fb36544
Binary files /dev/null and b/frappe/public/sounds/cancel.mp3 differ
diff --git a/frappe/public/sounds/chime.mp3 b/frappe/public/sounds/chime.mp3
new file mode 100644
index 0000000000..396883ecb4
Binary files /dev/null and b/frappe/public/sounds/chime.mp3 differ
diff --git a/frappe/public/sounds/click.mp3 b/frappe/public/sounds/click.mp3
new file mode 100644
index 0000000000..1c8480beec
Binary files /dev/null and b/frappe/public/sounds/click.mp3 differ
diff --git a/frappe/public/sounds/delete.mp3 b/frappe/public/sounds/delete.mp3
new file mode 100644
index 0000000000..6dd17ca812
Binary files /dev/null and b/frappe/public/sounds/delete.mp3 differ
diff --git a/frappe/public/sounds/email.mp3 b/frappe/public/sounds/email.mp3
new file mode 100644
index 0000000000..18e51631da
Binary files /dev/null and b/frappe/public/sounds/email.mp3 differ
diff --git a/frappe/public/sounds/error.mp3 b/frappe/public/sounds/error.mp3
new file mode 100644
index 0000000000..dca7767bfe
Binary files /dev/null and b/frappe/public/sounds/error.mp3 differ
diff --git a/frappe/public/sounds/submit.mp3 b/frappe/public/sounds/submit.mp3
new file mode 100644
index 0000000000..d3bc463ba6
Binary files /dev/null and b/frappe/public/sounds/submit.mp3 differ
diff --git a/frappe/templates/pages/desk.html b/frappe/templates/pages/desk.html
index 33d9c9161c..c954bc4c7b 100644
--- a/frappe/templates/pages/desk.html
+++ b/frappe/templates/pages/desk.html
@@ -61,4 +61,10 @@
{% endfor %}
{% include "templates/includes/google_analytics.html" %}
+
+ {% for sound in (sounds or []) %}
+
+ {% endfor %}