Oomox.php 10 KB

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