diff --git a/apps/theming/css/settings-admin.css b/apps/theming/css/settings-admin.css
index b0739465ef246a3bb05aa2ad4deab862a4debaaa..931e4d4508b41b0b827a3307cfc643e7cc6b44f2 100644
--- a/apps/theming/css/settings-admin.css
+++ b/apps/theming/css/settings-admin.css
@@ -22,3 +22,7 @@
 #theming .icon-upload {
     display: inline-flex;
 }
+
+div#theming_settings_msg {
+    margin-left: 10px;
+}
diff --git a/apps/theming/js/settings-admin.js b/apps/theming/js/settings-admin.js
index 7645654307675fd1c8d4a0370df5d909e9ffa888..dd2f051163c37aeac21c350f5cdb73be5b6e52af 100644
--- a/apps/theming/js/settings-admin.js
+++ b/apps/theming/js/settings-admin.js
@@ -20,9 +20,14 @@
  */
 
 function setThemingValue(setting, value) {
+	OC.msg.startSaving('#theming_settings_msg');
 	$.post(
 		OC.generateUrl('/apps/theming/ajax/updateStylesheet'), {'setting' : setting, 'value' : value}
-	);
+	).done(function(response) {
+		OC.msg.finishedSaving('#theming_settings_msg', response);
+	}).fail(function(response) {
+		OC.msg.finishedSaving('#theming_settings_msg', response);
+	});
 	preview(setting, value);
 }
 
@@ -45,12 +50,15 @@ $(document).ready(function () {
 
 	var uploadparms = {
 		pasteZone: null,
-		done: function (e, data) {
-			preview('logoName', data.result.name);
+		done: function (e, response) {
+			preview('logoName', response.result.data.name);
+			OC.msg.finishedSaving('#theming_settings_msg', response.result);
 		},
-		submit: function(e, data) {
+		submit: function(e, response) {
+			OC.msg.startSaving('#theming_settings_msg');
 		},
 		fail: function (e, data){
+			OC.msg.finishedSaving('#theming_settings_msg', response);
 		}
 	};
 	
@@ -86,18 +94,20 @@ $(document).ready(function () {
 	
 	$('.theme-undo').click(function (e) {
 		var setting = $(this).data('setting');
+		OC.msg.startSaving('#theming_settings_msg');
 		$.post(
 			OC.generateUrl('/apps/theming/ajax/undoChanges'), {'setting' : setting}
-		).done(function(data) {
+		).done(function(response) {
 			if (setting === 'color') {
 				var colorPicker = document.getElementById('theming-color');
-				colorPicker.style.backgroundColor = data.value;
-				colorPicker.value = data.value.slice(1);
+				colorPicker.style.backgroundColor = response.data.value;
+				colorPicker.value = response.data.value.slice(1);
 			} else if (setting !== 'logoName') {
 				var input = document.getElementById('theming-'+setting);
-				input.value = data.value;
+				input.value = response.data.value;
 			}
-			preview(setting, data.value);
+			preview(setting, response.data.value);
+			OC.msg.finishedSaving('#theming_settings_msg', response);
 		});
 	});
 });
diff --git a/apps/theming/lib/controller/themingcontroller.php b/apps/theming/lib/controller/themingcontroller.php
index 0aa95384a812a1b32a29c6b378ab4bdda6753a92..5ffbbf71769977968e3e345328cf980970630d8c 100644
--- a/apps/theming/lib/controller/themingcontroller.php
+++ b/apps/theming/lib/controller/themingcontroller.php
@@ -25,7 +25,9 @@ namespace OCA\Theming\Controller;
 
 use OCA\Theming\Template;
 use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http;
 use OCP\AppFramework\Http\DataResponse;
+use OCP\IL10N;
 use OCP\IRequest;
 
 /**
@@ -39,11 +41,28 @@ class ThemingController extends Controller {
 	
 	/** @var Template */
 	private $template;
-	
-	public function __construct($appName, IRequest $request, Template $template) {
+
+	/** @var IL10N */
+	private $l;
+
+	/**
+	 * ThemingController constructor.
+	 *
+	 * @param string $appName
+	 * @param IRequest $request
+	 * @param Template $template
+	 * @param IL10N $l
+	 */
+	public function __construct(
+		$appName,
+		IRequest $request,
+		Template $template,
+		IL10N $l
+	) {
 		parent::__construct($appName, $request);
 		
 		$this->template = $template;
+		$this->l = $l;
 	}
 
 	/**
@@ -54,7 +73,15 @@ class ThemingController extends Controller {
 	 */
 	public function updateStylesheet($setting, $value) {
 		$this->template->set($setting, $value);
-		return new DataResponse();
+		return new DataResponse(
+			[
+				'data' =>
+					[
+						'message' => $this->l->t('Saved')
+					],
+				'status' => 'success'
+			]
+		);
 	}
 
 	/**
@@ -65,12 +92,27 @@ class ThemingController extends Controller {
 	public function updateLogo() {
 		$newLogo = $this->request->getUploadedFile('uploadlogo');
 		if (empty($newLogo)) {
-			return new DataResponse(['message' => 'No logo uploaded'], Http::STATUS_UNPROCESSABLE_ENTITY);
+			return new DataResponse(
+				[
+					'data' => [
+						'message' => $this->l->t('No logo uploaded')
+					]
+				],
+				Http::STATUS_UNPROCESSABLE_ENTITY);
 		}
 		$this->template->set('logoName', $newLogo['name']);
 		rename($newLogo['tmp_name'], \OC::$SERVERROOT . '/themes/theming-app/core/img/' . $newLogo['name']);
 		
-		return new DataResponse(['name' => $newLogo['name']]);
+		return new DataResponse(
+			[
+				'data' =>
+					[
+						'name' => $newLogo['name'],
+						'message' => $this->l->t('Saved')
+					],
+				'status' => 'success'
+			]
+		);
 	}
 
 	/**
@@ -81,6 +123,15 @@ class ThemingController extends Controller {
 	 */
 	public function undo($setting) {
 		$value = $this->template->undo($setting);
-		return new DataResponse(['value' => $value]);
+		return new DataResponse(
+			[
+				'data' =>
+					[
+						'value' => $value,
+						'message' => $this->l->t('Saved')
+					],
+				'status' => 'success'
+			]
+		);
 	}
 }
diff --git a/apps/theming/templates/settings-admin.php b/apps/theming/templates/settings-admin.php
index cfc18de9c133a69f655f739b085f42aa4d84245a..4e2277b0533e228cd0c6f45a97756744287105e9 100644
--- a/apps/theming/templates/settings-admin.php
+++ b/apps/theming/templates/settings-admin.php
@@ -6,7 +6,8 @@ script('theming', '3rdparty/jscolor/jscolor');
 style('theming', 'settings-admin');
 ?>
 <div id="theming" class="section">
-	<h2><?php p($l->t('Theming')); ?></h2>
+	<h2 class="inlineblock"><?php p($l->t('Theming')); ?></h2>
+		<div id="theming_settings_msg" class="msg success inlineblock" style="display: none;">Saved</div>
 	<?php if ($_['themable'] === false) { ?>
 	<p>
 		<?php p($_['errorMessage']) ?>