This commit is contained in:
Jottyfan
2023-09-15 16:48:42 +02:00
parent b9981e3dc5
commit 80696b0c0b
12 changed files with 258 additions and 10 deletions

12
WEB-INF/web.xml Normal file
View 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>

View File

@ -8,7 +8,7 @@ plugins {
}
group = 'de.jottyfan.bico'
version = '0.0.0'
version = '0.0.1'
description = """BibleClassOrganizer"""
@ -41,7 +41,7 @@ war {
}
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-thymeleaf'

View File

@ -1,5 +1,10 @@
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
@ -7,4 +12,18 @@ package de.jottyfan.bico.modules;
*/
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;
}
}

View File

@ -1,6 +1,7 @@
package de.jottyfan.bico.modules.index;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import de.jottyfan.bico.modules.CommonController;
@ -13,7 +14,8 @@ import de.jottyfan.bico.modules.CommonController;
@Controller
public class IndexController extends CommonController {
@GetMapping("/")
public String getIndex() {
public String getIndex(Model model) {
useThemedModel(model);
return "redirect:/sheet";
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -20,7 +20,7 @@ public class SheetController extends CommonController {
@GetMapping("/sheet")
public String getSheet(Model model) {
model.addAttribute("list", service.getList());
useThemedModel(model).addAttribute("list", service.getList());
return "/sheet";
}
}

View File

@ -1,5 +1,21 @@
toggleDarkMode = function() {
var oldValue = $("html").attr("data-bs-theme");
var newValue = oldValue == "dark" ? "light" : "dark";
var updateUrl = /*[[@{/updateTheme}]]*/ 'updateTheme';
updateUrl = updateUrl + "/" + 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);
});

View File

@ -1,9 +1,5 @@
<!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">
<head>
<title>Camp Organizer 2</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<th:block layout:fragment="content">
<div class="borderdist">

View File

@ -1,7 +1,7 @@
<!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>
<title>Camp Organizer 2</title>
<title>Bible Class Organizer</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<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}" />