themeing
This commit is contained in:
12
WEB-INF/web.xml
Normal file
12
WEB-INF/web.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
|
||||||
|
<display-name>BiCO</display-name>
|
||||||
|
<welcome-file-list>
|
||||||
|
<welcome-file>index.html</welcome-file>
|
||||||
|
<welcome-file>index.htm</welcome-file>
|
||||||
|
<welcome-file>index.jsp</welcome-file>
|
||||||
|
<welcome-file>default.html</welcome-file>
|
||||||
|
<welcome-file>default.htm</welcome-file>
|
||||||
|
<welcome-file>default.jsp</welcome-file>
|
||||||
|
</welcome-file-list>
|
||||||
|
</web-app>
|
@ -8,7 +8,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = 'de.jottyfan.bico'
|
group = 'de.jottyfan.bico'
|
||||||
version = '0.0.0'
|
version = '0.0.1'
|
||||||
|
|
||||||
description = """BibleClassOrganizer"""
|
description = """BibleClassOrganizer"""
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ war {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'de.jottyfan:bicolib:1'
|
implementation 'de.jottyfan:bicolib:2'
|
||||||
|
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-jooq'
|
implementation 'org.springframework.boot:spring-boot-starter-jooq'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
package de.jottyfan.bico.modules;
|
package de.jottyfan.bico.modules;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
|
import de.jottyfan.bico.modules.profile.ProfileService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author jotty
|
* @author jotty
|
||||||
@ -7,4 +12,18 @@ package de.jottyfan.bico.modules;
|
|||||||
*/
|
*/
|
||||||
public abstract class CommonController {
|
public abstract class CommonController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ProfileService profileService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the theme for the current session
|
||||||
|
*
|
||||||
|
* @return the theme; light or dark at the moment
|
||||||
|
*/
|
||||||
|
public Model useThemedModel(Model model) {
|
||||||
|
// TODO: add profile's user name
|
||||||
|
String username = "jotty";
|
||||||
|
model.addAttribute("theme", profileService.getTheme(username));
|
||||||
|
return model;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package de.jottyfan.bico.modules.index;
|
package de.jottyfan.bico.modules.index;
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
import de.jottyfan.bico.modules.CommonController;
|
import de.jottyfan.bico.modules.CommonController;
|
||||||
@ -13,7 +14,8 @@ import de.jottyfan.bico.modules.CommonController;
|
|||||||
@Controller
|
@Controller
|
||||||
public class IndexController extends CommonController {
|
public class IndexController extends CommonController {
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public String getIndex() {
|
public String getIndex(Model model) {
|
||||||
|
useThemedModel(model);
|
||||||
return "redirect:/sheet";
|
return "redirect:/sheet";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
package de.jottyfan.bico.modules.profile;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import de.jottyfan.bico.modules.CommonController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class ProfileController extends CommonController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ProfileService service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update the theme of the current user
|
||||||
|
*
|
||||||
|
* @param theme the theme
|
||||||
|
*/
|
||||||
|
@PostMapping("/updateTheme/{theme}")
|
||||||
|
public ResponseEntity<?> updateTheme(@PathVariable String theme) {
|
||||||
|
// TODO: add profile's user name
|
||||||
|
String username = "jotty";
|
||||||
|
service.updateTheme(username, theme);
|
||||||
|
return ResponseEntity.ok(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package de.jottyfan.bico.modules.profile;
|
||||||
|
|
||||||
|
import static de.jottyfan.bico.db.Tables.T_PROFILE;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jooq.DSLContext;
|
||||||
|
import org.jooq.InsertOnDuplicateSetMoreStep;
|
||||||
|
import org.jooq.SelectConditionStep;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import de.jottyfan.bico.db.tables.records.TProfileRecord;
|
||||||
|
import de.jottyfan.bico.modules.profile.model.ProfileBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public class ProfileRepository {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(ProfileRepository.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DSLContext jooq;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the profile of the user
|
||||||
|
*
|
||||||
|
* @param username the name of the user
|
||||||
|
* @return the profile or null if not found
|
||||||
|
*/
|
||||||
|
public ProfileBean getProfile(String username) {
|
||||||
|
SelectConditionStep<TProfileRecord> sql = jooq
|
||||||
|
// @formatter:off
|
||||||
|
.selectFrom(T_PROFILE)
|
||||||
|
.where(T_PROFILE.USERNAME.eq(username));
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.trace(sql.toString());
|
||||||
|
TProfileRecord r = sql.fetchOne();
|
||||||
|
if (r != null) {
|
||||||
|
return ProfileBean.of(username).withTheme(r.getTheme());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* upsert theme for username
|
||||||
|
*
|
||||||
|
* @param username the name of the user
|
||||||
|
* @param theme the selected theme; may be light or dark
|
||||||
|
* @return number of affected database rows; should be 1
|
||||||
|
*/
|
||||||
|
public Integer upsertTheme(String username, String theme) {
|
||||||
|
InsertOnDuplicateSetMoreStep<TProfileRecord> sql = jooq
|
||||||
|
// @formatter:off
|
||||||
|
.insertInto(T_PROFILE,
|
||||||
|
T_PROFILE.USERNAME,
|
||||||
|
T_PROFILE.THEME)
|
||||||
|
.values(username, theme)
|
||||||
|
.onConflict(T_PROFILE.USERNAME)
|
||||||
|
.doUpdate()
|
||||||
|
.setAllToExcluded();
|
||||||
|
// @formatter:on
|
||||||
|
LOGGER.trace(sql.toString());
|
||||||
|
return sql.execute();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package de.jottyfan.bico.modules.profile;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import de.jottyfan.bico.modules.profile.model.ProfileBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ProfileService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ProfileRepository repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the theme of the user
|
||||||
|
*
|
||||||
|
* @param username the name of the user
|
||||||
|
* @return the theme of the user
|
||||||
|
*/
|
||||||
|
public String getTheme(String username) {
|
||||||
|
ProfileBean bean = repository.getProfile(username);
|
||||||
|
return bean == null ? "light" : bean.getTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update the theme of the user
|
||||||
|
*
|
||||||
|
* @param username the name of the user
|
||||||
|
* @param theme the theme; may be light or dark
|
||||||
|
*/
|
||||||
|
public void updateTheme(String username, String theme) {
|
||||||
|
repository.upsertTheme(username, theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package de.jottyfan.bico.modules.profile.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ProfileBean implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
private String theme;
|
||||||
|
|
||||||
|
public static final ProfileBean of(String username) {
|
||||||
|
ProfileBean bean = new ProfileBean();
|
||||||
|
bean.setUsername(username);
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final ProfileBean of(String username, String theme) {
|
||||||
|
return ProfileBean.of(username).withTheme(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileBean withTheme(String theme) {
|
||||||
|
this.theme = theme;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the username
|
||||||
|
*/
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param username the username to set
|
||||||
|
*/
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the theme
|
||||||
|
*/
|
||||||
|
public String getTheme() {
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param theme the theme to set
|
||||||
|
*/
|
||||||
|
public void setTheme(String theme) {
|
||||||
|
this.theme = theme;
|
||||||
|
}
|
||||||
|
}
|
@ -20,7 +20,7 @@ public class SheetController extends CommonController {
|
|||||||
|
|
||||||
@GetMapping("/sheet")
|
@GetMapping("/sheet")
|
||||||
public String getSheet(Model model) {
|
public String getSheet(Model model) {
|
||||||
model.addAttribute("list", service.getList());
|
useThemedModel(model).addAttribute("list", service.getList());
|
||||||
return "/sheet";
|
return "/sheet";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
toggleDarkMode = function() {
|
toggleDarkMode = function() {
|
||||||
var oldValue = $("html").attr("data-bs-theme");
|
var oldValue = $("html").attr("data-bs-theme");
|
||||||
var newValue = oldValue == "dark" ? "light" : "dark";
|
var newValue = oldValue == "dark" ? "light" : "dark";
|
||||||
|
var updateUrl = /*[[@{/updateTheme}]]*/ 'updateTheme';
|
||||||
|
updateUrl = updateUrl + "/" + newValue;
|
||||||
$("html").attr("data-bs-theme", newValue);
|
$("html").attr("data-bs-theme", newValue);
|
||||||
|
$.ajax({
|
||||||
|
url: updateUrl,
|
||||||
|
type: "POST",
|
||||||
|
contentType: "application/json",
|
||||||
|
dataType: 'json'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* only because th:data-bs-theme="${theme}" does not work
|
||||||
|
*/
|
||||||
|
$(document).ready(function(){
|
||||||
|
var theme = /*[[${theme}]]*/ 'dark';
|
||||||
|
$("html").attr("data-bs-theme", theme);
|
||||||
|
});
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{template}" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
<html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{template}" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
<head>
|
|
||||||
<title>Camp Organizer 2</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<th:block layout:fragment="content">
|
<th:block layout:fragment="content">
|
||||||
<div class="borderdist">
|
<div class="borderdist">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security" data-bs-theme="dark">
|
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
<head>
|
<head>
|
||||||
<title>Camp Organizer 2</title>
|
<title>Bible Class Organizer</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<link th:rel="stylesheet" type="text/css" media="all" th:href="@{/webjars/bootstrap/5.3.1/css/bootstrap.min.css}" />
|
<link th:rel="stylesheet" type="text/css" media="all" th:href="@{/webjars/bootstrap/5.3.1/css/bootstrap.min.css}" />
|
||||||
|
Reference in New Issue
Block a user