Oomox.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <?php
  2. declare(strict_types=1);
  3. // {{{ License
  4. // This file is part of GNU social - https://www.gnu.org/software/social
  5. //
  6. // GNU social is free software: you can redistribute it and/or modify
  7. // it under the terms of the GNU Affero General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // GNU social is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU Affero General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU Affero General Public License
  17. // along with GNU social. If not, see <http://www.gnu.org/licenses/>.
  18. // }}}
  19. namespace Plugin\Oomox\Controller;
  20. use App\Core\Cache;
  21. use App\Core\DB\DB;
  22. use App\Core\Form;
  23. use App\Util\Common;
  24. use App\Util\Exception\ClientException;
  25. use App\Util\Exception\NoLoggedInUser;
  26. use App\Util\Exception\RedirectException;
  27. use App\Util\Exception\ServerException;
  28. use App\Util\Formatting;
  29. use Plugin\Oomox\Entity\Oomox as EntityOomox;
  30. use Plugin\Oomox\Oomox as PluginOomox;
  31. use Symfony\Component\Form\Extension\Core\Type\ColorType;
  32. use Symfony\Component\Form\Extension\Core\Type\HiddenType;
  33. use Symfony\Component\Form\Extension\Core\Type\SubmitType;
  34. use Symfony\Component\Form\FormInterface;
  35. use Symfony\Component\Form\SubmitButton;
  36. use Symfony\Component\HttpFoundation\Request;
  37. use Symfony\Component\HttpFoundation\Response;
  38. use function App\Core\I18n\_m;
  39. use function is_null;
  40. /**
  41. * Oomox controller
  42. *
  43. * @package GNUsocial
  44. * @category Oomox
  45. *
  46. * @author Eliseu Amaro <mail@eliseuama.ro>
  47. * @copyright 2020 Free Software Foundation, Inc http://www.fsf.org
  48. * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
  49. */
  50. class Oomox
  51. {
  52. /**
  53. * Generates a FormInterface depending on current theme settings and system-wide colour preference.
  54. * Receives the user's Oomox entity, and wether or not its intended for dark of light theme to change its behaviour accordingly.
  55. *
  56. * @throws ServerException
  57. */
  58. public function getOomoxForm(?EntityOomox $current_oomox_settings, bool $is_light): FormInterface
  59. {
  60. $theme = $is_light ? 'light' : 'dark';
  61. $foreground = 'colour_foreground_' . $theme;
  62. $background_hard = 'colour_background_hard_' . $theme;
  63. $background_card = 'colour_background_card_' . $theme;
  64. $border = 'colour_border_' . $theme;
  65. $accent = 'colour_accent_' . $theme;
  66. $reset = 'colour_reset_' . $theme;
  67. $save = 'save_oomox_colours_' . $theme;
  68. if (isset($current_oomox_settings)) {
  69. if ($is_light) {
  70. $current_foreground = $current_oomox_settings->getColourForegroundLight() ?: '#09090d';
  71. $current_background_hard = $current_oomox_settings->getColourBackgroundHardLight() ?: '#ebebeb';
  72. $current_background_card = $current_oomox_settings->getColourBackgroundCardLight() ?: '#f0f0f0';
  73. $current_border = $current_oomox_settings->getColourBorderLight() ?: '#d5d5d5';
  74. $current_accent = $current_oomox_settings->getColourAccentLight() ?: '#a22430';
  75. } else {
  76. $current_foreground = $current_oomox_settings->getColourForegroundDark() ?: '#f0f6f6';
  77. $current_background_hard = $current_oomox_settings->getColourBackgroundHardDark() ?: '#141216';
  78. $current_background_card = $current_oomox_settings->getColourBackgroundCardDark() ?: '#131217';
  79. $current_border = $current_oomox_settings->getColourBorderDark() ?: '#201f25';
  80. $current_accent = $current_oomox_settings->getColourAccentDark() ?: '#5ddbcf';
  81. }
  82. } else {
  83. $current_foreground = $is_light ? '#09090d' : '#f0f6f6';
  84. $current_background_hard = $is_light ? '#ebebeb' : '#141216';
  85. $current_background_card = $is_light ? '#f0f0f0' : '#131217';
  86. $current_border = $is_light ? '#d5d5d5' : '#201f25';
  87. $current_accent = $is_light ? '#a22430' : '#5ddbcf';
  88. }
  89. return Form::create([
  90. [$foreground, ColorType::class, [
  91. 'html5' => true,
  92. 'data' => $current_foreground,
  93. 'label' => _m('Foreground colour'),
  94. 'help' => _m('Choose the foreground colour'),],
  95. ],
  96. [$background_hard, ColorType::class, [
  97. 'html5' => true,
  98. 'data' => $current_background_hard,
  99. 'label' => _m('Background colour'),
  100. 'help' => _m('Choose the background colour'),],
  101. ],
  102. [$background_card, ColorType::class, [
  103. 'html5' => true,
  104. 'data' => $current_background_card,
  105. 'label' => _m('Card background colour'),
  106. 'help' => _m('Choose the card background colour'),],
  107. ],
  108. [$border, ColorType::class, [
  109. 'html5' => true,
  110. 'data' => $current_border,
  111. 'label' => _m('Border colour'),
  112. 'help' => _m('Choose the borders accents'),],
  113. ],
  114. [$accent, ColorType::class, [
  115. 'html5' => true,
  116. 'data' => $current_accent,
  117. 'label' => _m('Accent colour'),
  118. 'help' => _m('Choose the accent colour'),],
  119. ],
  120. ['hidden', HiddenType::class, []],
  121. [$reset, SubmitType::class, ['label' => _m('Reset colours to default')]],
  122. [$save, SubmitType::class, ['label' => _m('Submit')]],
  123. ]);
  124. }
  125. /**
  126. * Handles Light theme settings tab
  127. *
  128. * @throws NoLoggedInUser
  129. * @throws RedirectException
  130. * @throws ServerException
  131. */
  132. public static function oomoxSettingsLight(Request $request): array
  133. {
  134. $user = Common::ensureLoggedIn();
  135. $actor_id = $user->getId();
  136. $current_oomox_settings = PluginOomox::getEntity($user);
  137. $form_light = (new self)->getOomoxForm($current_oomox_settings, true);
  138. $form_light->handleRequest($request);
  139. if ($form_light->isSubmitted() && $form_light->isValid()) {
  140. /** @var SubmitButton $reset_button */
  141. $reset_button = $form_light->get('colour_reset_light');
  142. if ($reset_button->isClicked()) {
  143. if (isset($current_oomox_settings)) {
  144. $current_oomox_settings?->resetTheme(true);
  145. }
  146. } else {
  147. $data = $form_light->getData();
  148. $current_oomox_settings = EntityOomox::create(
  149. [
  150. 'actor_id' => $actor_id,
  151. 'colour_foreground_light' => $data['colour_foreground_light'],
  152. 'colour_background_hard_light' => $data['colour_background_hard_light'],
  153. 'colour_background_card_light' => $data['colour_background_card_light'],
  154. 'colour_border_light' => $data['colour_border_light'],
  155. 'colour_accent_light' => $data['colour_accent_light'],
  156. ],
  157. );
  158. }
  159. DB::merge($current_oomox_settings);
  160. DB::flush();
  161. Cache::delete(PluginOomox::cacheKey($user));
  162. throw new RedirectException();
  163. }
  164. return ['_template' => 'oomox/oomoxSettingsLight.html.twig', 'oomoxLight' => $form_light->createView()];
  165. }
  166. /**
  167. * Handles the Dark theme settings tab
  168. *
  169. * @throws NoLoggedInUser
  170. * @throws RedirectException
  171. * @throws ServerException
  172. */
  173. public static function oomoxSettingsDark(Request $request): array
  174. {
  175. $user = Common::ensureLoggedIn();
  176. $actor_id = $user->getId();
  177. $current_oomox_settings = PluginOomox::getEntity($user);
  178. $form_dark = (new self)->getOomoxForm($current_oomox_settings, false);
  179. $form_dark->handleRequest($request);
  180. if ($form_dark->isSubmitted() && $form_dark->isValid()) {
  181. $reset_button = $form_dark->get('colour_reset_dark');
  182. /** @var SubmitButton $reset_button */
  183. if ($reset_button->isClicked()) {
  184. $current_oomox_settings?->resetTheme(false);
  185. } else {
  186. $data = $form_dark->getData();
  187. $current_oomox_settings = EntityOomox::create(
  188. [
  189. 'actor_id' => $actor_id,
  190. 'colour_foreground_dark' => $data['colour_foreground_dark'],
  191. 'colour_background_hard_dark' => $data['colour_background_hard_dark'],
  192. 'colour_background_card_dark' => $data['colour_background_card_dark'],
  193. 'colour_border_dark' => $data['colour_border_dark'],
  194. 'colour_accent_dark' => $data['colour_accent_dark'],
  195. ],
  196. );
  197. }
  198. DB::merge($current_oomox_settings);
  199. DB::flush();
  200. Cache::delete(PluginOomox::cacheKey($user));
  201. throw new RedirectException();
  202. }
  203. return ['_template' => 'oomox/oomoxSettingsDark.html.twig', 'oomoxDark' => $form_dark->createView()];
  204. }
  205. /**
  206. * Renders the resulting CSS file from user options, serves that file as a response
  207. *
  208. * @return Response
  209. * @throws NoLoggedInUser
  210. * @throws ServerException
  211. *
  212. * @throws ClientException
  213. */
  214. public function oomoxCSS(): Response
  215. {
  216. $user = Common::ensureLoggedIn();
  217. $oomox_table = PluginOomox::getEntity($user);
  218. if (is_null($oomox_table)) {
  219. throw new ClientException(_m('No custom colours defined', 404));
  220. }
  221. $content = Formatting::twigRenderFile('/oomox/root_override.css.twig', ['oomox' => $oomox_table]);
  222. return new Response($content, status: 200, headers: ['content-type' => 'text/css']);
  223. }
  224. }