#120 Theme system

This commit is contained in:
Daniel Brendel
2024-03-04 22:05:03 +01:00
parent 0334d3e668
commit 0a56ebab88
17 changed files with 219 additions and 8 deletions
+1
View File
@@ -55,6 +55,7 @@ users have taken. The system features collaborative management, so you can manag
- 🕰️ History feature
- 💬 Group chat
- ⚙️ Profile management
- 🦋 Themes
- 🔑 Admin dashboard
- 📢 Reminders
- 💾 Backups
+6
View File
@@ -53,6 +53,12 @@ class BaseController extends Asatru\Controller\Controller {
UtilsModule::setLanguage($lang);
}
}
$theme = $auth_user->get('theme');
if (($theme) && (is_dir(public_path() . '/themes/' . $theme))) {
ThemeModule::load(public_path() . '/themes/' . $theme);
}
}
}
+2 -1
View File
@@ -65,13 +65,14 @@ class UserController extends BaseController {
$name = $request->params()->query('name', null);
$email = $request->params()->query('email', null);
$lang = $request->params()->query('lang', 'en');
$theme = $request->params()->query('theme', 'default');
$chatcolor = $request->params()->query('chatcolor', null);
$show_log = $request->params()->query('show_log', false);
$notify_tasks_overdue = $request->params()->query('notify_tasks_overdue', false);
$notify_tasks_tomorrow = $request->params()->query('notify_tasks_tomorrow', false);
$show_plants_aoru = $request->params()->query('show_plants_aoru', 'added');
UserModel::editPreferences($name, $email, $lang, $chatcolor, $show_log, $notify_tasks_overdue, $notify_tasks_tomorrow, $show_plants_aoru);
UserModel::editPreferences($name, $email, $lang, $theme, $chatcolor, $show_log, $notify_tasks_overdue, $notify_tasks_tomorrow, $show_plants_aoru);
$password = $request->params()->query('password', null);
if ($password) {
+3 -1
View File
@@ -260,5 +260,7 @@ return [
'import_successful' => 'Erfolgreich importiert!',
'pwa_enable' => 'PWA Unterstützung aktivieren',
'home' => 'Home',
'enable_system_messages' => 'Systemmeldungen aktivieren'
'enable_system_messages' => 'Systemmeldungen aktivieren',
'theme' => 'Theme',
'themes' => 'Themes'
];
+3 -1
View File
@@ -263,5 +263,7 @@ return [
'enable_system_messages' => 'Enable system messages',
'plant_count' => '{count} plants',
'danger_count' => '{count} in danger',
'all_in_good_standing' => 'All fine'
'all_in_good_standing' => 'All fine',
'theme' => 'Theme',
'themes' => 'Themes'
];
+1
View File
@@ -38,6 +38,7 @@ class UserModel_Migration {
$this->database->add('lang VARCHAR(512) NULL');
$this->database->add('chatcolor VARCHAR(512) NULL');
$this->database->add('notes TEXT NULL');
$this->database->add('theme VARCHAR(512) NULL');
$this->database->add('show_log BOOLEAN NOT NULL DEFAULT 1');
$this->database->add('show_plants_aoru BOOLEAN NOT NULL DEFAULT 1');
$this->database->add('notify_tasks_overdue BOOLEAN NOT NULL DEFAULT 1');
+4 -3
View File
@@ -182,6 +182,7 @@ class UserModel extends \Asatru\Database\Model {
* @param $name
* @param $email
* @param $lang
* @param $theme
* @param $chatcolor
* @param $show_log
* @param $notify_tasks_overdue
@@ -190,7 +191,7 @@ class UserModel extends \Asatru\Database\Model {
* @return void
* @throws \Exception
*/
public static function editPreferences($name, $email, $lang, $chatcolor, $show_log, $notify_tasks_overdue, $notify_tasks_tomorrow, $show_plants_aoru)
public static function editPreferences($name, $email, $lang, $theme, $chatcolor, $show_log, $notify_tasks_overdue, $notify_tasks_tomorrow, $show_plants_aoru)
{
try {
$user = static::getAuthUser();
@@ -198,8 +199,8 @@ class UserModel extends \Asatru\Database\Model {
throw new \Exception('User not authenticated');
}
static::raw('UPDATE `' . self::tableName() . '` SET name = ?, email = ?, lang = ?, chatcolor = ?, show_log = ?, notify_tasks_overdue = ?, notify_tasks_tomorrow = ?, show_plants_aoru = ? WHERE id = ?', [
trim($name), trim($email), $lang, $chatcolor, $show_log, $notify_tasks_overdue, $notify_tasks_tomorrow, (int)$show_plants_aoru, $user->get('id')
static::raw('UPDATE `' . self::tableName() . '` SET name = ?, email = ?, lang = ?, theme = ?, chatcolor = ?, show_log = ?, notify_tasks_overdue = ?, notify_tasks_tomorrow = ?, show_plants_aoru = ? WHERE id = ?', [
trim($name), trim($email), $lang, $theme, $chatcolor, $show_log, $notify_tasks_overdue, $notify_tasks_tomorrow, (int)$show_plants_aoru, $user->get('id')
]);
} catch (\Exception $e) {
throw $e;
+122
View File
@@ -0,0 +1,122 @@
<?php
/**
* This class represents your module
*/
class ThemeModule {
/** @var array $theme_data */
public static $theme_data = null;
/**
* @param $path
* @return void
* @throws \Exception
*/
public static function load($path)
{
try {
self::$theme_data = null;
self::$theme_data = json_decode(file_get_contents($path . '/layout.json'));
if (!is_object(self::$theme_data)) {
throw new \Exception('Invalid data @ ' . $path . '/layout.json: ' . print_r(self::$theme_data, true));
}
if (!file_exists($path . '/' . self::$theme_data->banner)) {
throw new \Exception('Banner asset not found');
}
self::$theme_data->banner_url = asset('themes/' . self::$theme_data->name . '/' . self::$theme_data->banner);
self::$theme_data->inline_rules = '';
foreach (self::$theme_data->rules as $key => $value) {
self::$theme_data->inline_rules .= $key . ': ' . $value . ' !important;';
}
if (isset(self::$theme_data->icon)) {
if (!file_exists($path . '/' . self::$theme_data->icon->asset)) {
throw new \Exception('Icon asset not found');
}
self::$theme_data->icon->url = asset('themes/' . self::$theme_data->name . '/' . self::$theme_data->icon->asset);
self::$theme_data->icon->inline_rules = new \stdClass();
self::$theme_data->icon->inline_rules->base = '';
foreach (self::$theme_data->icon->base as $key => $value) {
self::$theme_data->icon->inline_rules->base .= $key . ': ' . $value . ' !important;';
}
self::$theme_data->icon->inline_rules->img = '';
foreach (self::$theme_data->icon->img as $key => $value) {
self::$theme_data->icon->inline_rules->img .= $key . ': ' . $value . ' !important;';
}
}
if (isset(self::$theme_data->accessory)) {
if (!file_exists($path . '/' . self::$theme_data->accessory->asset)) {
throw new \Exception('Icon asset not found');
}
self::$theme_data->accessory->url = asset('themes/' . self::$theme_data->name . '/' . self::$theme_data->accessory->asset);
self::$theme_data->accessory->inline_rules = new \stdClass();
self::$theme_data->accessory->inline_rules->base = '';
foreach (self::$theme_data->accessory->base as $key => $value) {
self::$theme_data->accessory->inline_rules->base .= $key . ': ' . $value . ' !important;';
}
self::$theme_data->accessory->inline_rules->img = '';
foreach (self::$theme_data->accessory->img as $key => $value) {
self::$theme_data->accessory->inline_rules->img .= $key . ': ' . $value . ' !important;';
}
}
} catch (\Exception $e) {
throw $e;
}
}
/**
* @return mixed
* @throws \Exception
*/
public static function data()
{
try {
return self::$theme_data;
} catch (\Exception $e) {
throw $e;
}
}
/**
* @return bool
*/
public static function ready()
{
return (is_object(self::$theme_data));
}
/**
* @return array
* @throws \Exception
*/
public static function list()
{
try {
$result = [];
$folders = scandir(public_path() . '/themes');
foreach ($folders as $folder) {
if (((substr($folder, 0, 1)) !== '.') && (is_dir(public_path() . '/themes/' . $folder))) {
$result[] = $folder;
}
}
return $result;
} catch (\Exception $e) {
throw $e;
}
}
}
+11
View File
@@ -284,6 +284,17 @@ a.navbar-burger:hover {
height: 72px;
}
.banner-accessory {
position: relative;
top: 172px;
right: -83%;
}
.banner-accessory img {
width: 256px;
height: 256px;
}
.content-inner {
position: relative;
padding: 15px;
+6
View File
@@ -4,4 +4,10 @@
<img src="{{ asset('img/banner-icon.png') }}" alt="banner-icon"/>
</div>
@endif
@if (file_exists(public_path() . '/img/banner-accessory.png'))
<div class="banner-accessory">
<img src="{{ asset('img/banner-accessory.png') }}" alt="banner-accessory"/>
</div>
@endif
</div>
+17 -1
View File
@@ -24,7 +24,12 @@
<div id="scroller-top"></div>
@include('navbar.php')
@include('banner.php')
@if (ThemeModule::ready())
@include('theme.php')
@else
@include('banner.php')
@endif
<div id="small-system-messages"></div>
@@ -643,6 +648,17 @@
</div>
</div>
<div class="field">
<label class="label">{{ __('app.theme') }}</label>
<div class="control">
<select class="input" name="theme" id="selEditCombo">
@foreach (ThemeModule::list() as $theme)
<option value="{{ $theme }}" {{ ($user->get('theme') === $theme) ? 'selected' : ''}}>{{ $theme }}</option>
@endforeach
</select>
</div>
</div>
<div class="field {{ ((!app('chat_enable')) ? 'is-hidden': '') }}">
<label class="label">{{ __('app.chatcolor') }}</label>
<div class="control">
+13
View File
@@ -0,0 +1,13 @@
<div class="banner" style="background-image: url('{{ ThemeModule::data()->banner_url }}'); {{ ThemeModule::data()->inline_rules }}">
@if (isset(ThemeModule::data()->icon))
<div class="banner-icon" style="{{ ThemeModule::data()->icon->inline_rules->base }}">
<img src="{{ ThemeModule::data()->icon->url }}" alt="banner-icon" style="{{ ThemeModule::data()->icon->inline_rules->img }}"/>
</div>
@endif
@if (isset(ThemeModule::data()->accessory))
<div class="banner-accessory" style="{{ ThemeModule::data()->accessory->inline_rules->base }}">
<img src="{{ ThemeModule::data()->accessory->url }}" alt="banner-accessory" style="{{ ThemeModule::data()->accessory->inline_rules->img }}"/>
</div>
@endif
</div>
+1 -1
View File
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 837 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

+29
View File
@@ -0,0 +1,29 @@
{
"name": "default",
"banner": "banner.jpg",
"rules": {
"height": "250px"
},
"icon": {
"asset": "banner-icon.png",
"base": {
"top": "210px",
"left": "195px"
},
"img": {
"width": "72px",
"height": "72px"
}
},
"accessory": {
"asset": "banner-accessory.png",
"base": {
"top": "172px",
"right": "-83%"
},
"img": {
"width": "256px",
"height": "256px"
}
}
}