....
This commit is contained in:
@@ -3,6 +3,9 @@ package kr.lunaticbum.back.lun.controllers
|
||||
import com.drew.imaging.ImageMetadataReader
|
||||
import com.drew.metadata.Metadata
|
||||
import com.google.gson.Gson
|
||||
import com.google.maps.GeoApiContext
|
||||
import com.google.maps.GeocodingApi
|
||||
import com.google.maps.model.LatLng
|
||||
import jakarta.servlet.http.HttpServletRequest
|
||||
import jakarta.servlet.http.HttpServletResponse
|
||||
import kr.lunaticbum.back.lun.configs.GlobalEnvironment
|
||||
@@ -13,15 +16,22 @@ import kr.lunaticbum.back.lun.model.*
|
||||
import kr.lunaticbum.back.lun.service.JwtService
|
||||
import kr.lunaticbum.back.lun.utils.LogService
|
||||
import kr.lunaticbum.back.lun.utils.getFileExtension
|
||||
import org.commonmark.node.Node
|
||||
import org.commonmark.parser.Parser
|
||||
import org.commonmark.renderer.html.HtmlRenderer
|
||||
import org.jsoup.Jsoup
|
||||
import org.jsoup.nodes.Element
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.core.io.Resource
|
||||
import org.springframework.core.io.UrlResource
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
import org.springframework.web.reactive.function.client.WebClient
|
||||
import reactor.kotlin.core.publisher.toMono
|
||||
import java.io.*
|
||||
import java.net.URLDecoder
|
||||
import java.text.SimpleDateFormat
|
||||
@@ -131,6 +141,23 @@ class BlogController() {
|
||||
postManageg.getPost(postId).block().apply {
|
||||
this?.title = URLDecoder.decode(this?.title)
|
||||
this?.content = URLDecoder.decode(this?.content)
|
||||
|
||||
|
||||
|
||||
globalEvv.gapiKey?.let {
|
||||
if (this?.firstAddress?.length ?: 0 < 4){
|
||||
try {
|
||||
var addrs = GeocodingApi.reverseGeocode(GeoApiContext.Builder().apiKey(it).build(), LatLng(this?.firstPostLat!!,this?.firstPostLon!!)).await()
|
||||
this.firstAddress = addrs.first().formattedAddress
|
||||
} catch (e: Exception) {}
|
||||
}
|
||||
if (this?.modifyAddress?.length ?: 0 < 4){
|
||||
try {
|
||||
var addrs = GeocodingApi.reverseGeocode(GeoApiContext.Builder().apiKey(it).build(), LatLng(this?.modifyLat!!,this?.modifyLon!!)).await()
|
||||
this.modifyAddress = addrs.first().formattedAddress
|
||||
} catch (e: Exception) {}
|
||||
}
|
||||
}
|
||||
vm.modelMap.put("srcPost",this)
|
||||
}
|
||||
return vm
|
||||
@@ -175,6 +202,31 @@ class BlogController() {
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("posts")
|
||||
fun posts() : ResultMV{
|
||||
val vm = ResultMV("content/blog/posts")
|
||||
try {
|
||||
vm.modelMap.put("Posts", postManageg.find20().apply {
|
||||
this.forEach {
|
||||
it.title = URLDecoder.decode(it.title)
|
||||
it.content = URLDecoder.decode(it.content)
|
||||
val parser: Parser = Parser.builder().build()
|
||||
val document: Node = parser.parse(it.content)
|
||||
val renderer = HtmlRenderer.builder().build()
|
||||
Jsoup.parse(renderer.render(document))?.let { doc ->
|
||||
val firstImg: Element? = doc.select("img")?.first()
|
||||
val imgSrc: String = firstImg?.attr("src") ?: ""
|
||||
it.image = imgSrc
|
||||
it.html = doc.text()
|
||||
}
|
||||
it.title = if ((it.title?.length ?: 0) >= 1) it.title else ""
|
||||
}
|
||||
}.chunked(2))
|
||||
}catch (ex: Exception){ex.printStackTrace()}
|
||||
|
||||
return vm
|
||||
}
|
||||
|
||||
@GetMapping("recent")
|
||||
fun recent() : ResultMV{
|
||||
val vm = ResultMV("content/blog/viewer")
|
||||
|
||||
@@ -42,6 +42,8 @@ class Post {
|
||||
var posting : Boolean = false
|
||||
var firstPostLat : Double = 0.0
|
||||
var firstPostLon : Double = 0.0
|
||||
var firstAddress = ""
|
||||
var modifyAddress = ""
|
||||
|
||||
var modifyTime : Long = 0
|
||||
var modifyLat : Double = 0.0
|
||||
|
||||
@@ -158,9 +158,9 @@ a.btn_layerClose:hover {
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
#editor {
|
||||
border: 1px solid #393b42;
|
||||
padding: 1px;
|
||||
border-radius: 10px;
|
||||
background: #00000044;
|
||||
}
|
||||
/*#editor {*/
|
||||
/* border: 1px solid #393b42;*/
|
||||
/* padding: 1px;*/
|
||||
/* border-radius: 10px;*/
|
||||
/* background: #00000044;*/
|
||||
/*}*/
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
|
||||
onload = function() {
|
||||
history.replaceState({}, null, location.pathname);
|
||||
var accToken = get_cookie("access")
|
||||
var refreshToken = get_cookie("refresh")
|
||||
console.log("access === " + accToken + " || " + accToken.length);
|
||||
console.log("refresh === " + refreshToken + " || " + refreshToken.length);
|
||||
// var accToken = get_cookie("access")
|
||||
// var refreshToken = get_cookie("refresh")
|
||||
// console.log("access === " + accToken + " || " + accToken.length);
|
||||
// console.log("refresh === " + refreshToken + " || " + refreshToken.length);
|
||||
document.cookie = "access=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
|
||||
document.cookie = "refresh=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
|
||||
document.cookie = "CLEAR=; expires=Thu, 01 Jan 1970 00:00:01 GMT;"
|
||||
}
|
||||
onbeforeunload = function () {
|
||||
var accToken = get_cookie("access")
|
||||
var refreshToken = get_cookie("refresh")
|
||||
console.log("access === " + accToken + " || " + accToken.length);
|
||||
console.log("refresh === " + refreshToken + " || " + refreshToken.length);
|
||||
|
||||
if (accToken.length < 1) {
|
||||
document.cookie = "refresh="+ window.sessionStorage.getItem("REFRESH") + ";";
|
||||
}
|
||||
if (refreshToken.length < 1) {
|
||||
window.sessionStorage.setItem("REFRESH",get_cookie("refresh"))
|
||||
}
|
||||
}
|
||||
// onbeforeunload = function () {
|
||||
// var accToken = get_cookie("access")
|
||||
// var refreshToken = get_cookie("refresh")
|
||||
// console.log("access === " + accToken + " || " + accToken.length);
|
||||
// console.log("refresh === " + refreshToken + " || " + refreshToken.length);
|
||||
//
|
||||
// if (accToken.length < 1) {
|
||||
// document.cookie = "refresh="+ window.sessionStorage.getItem("REFRESH") + ";";
|
||||
// }
|
||||
// if (refreshToken.length < 1) {
|
||||
// window.sessionStorage.setItem("REFRESH",get_cookie("refresh"))
|
||||
// }
|
||||
// }
|
||||
function get_cookie(name) {
|
||||
var value = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
|
||||
return value? value[2] : null;
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
<!DOCTYPE html>
|
||||
<html
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{layout/default_layout}"
|
||||
>
|
||||
<th:block layout:fragment="head">
|
||||
<script type="text/javascript" th:src="@{/js/toast-ui-view.js}"></script>
|
||||
<link th:href="@{/css/toast-ui-dark.css}" rel="stylesheet" />
|
||||
<script type="text/javascript" th:src="@{/js/blog.js}"></script>
|
||||
<link th:href="@{/css/blog.css}" rel="stylesheet" />
|
||||
<script th:inline="javascript">
|
||||
let editor
|
||||
let onChange = () => {console.log(editor.getMarkdown())}
|
||||
document.addEventListener("DOMContentLoaded", onLoaded);
|
||||
function onLoaded() {
|
||||
// 1. 모든 'current' 클래스를 가진 요소를 선택하고 제거
|
||||
const currentElements = document.querySelectorAll('.current');
|
||||
currentElements.forEach(element => {
|
||||
element.classList.remove('current');
|
||||
});
|
||||
|
||||
// 2. 특정 조건에 맞는 요소에 'current' 클래스 추가 (예: ID가 'targetElement'인 요소)
|
||||
const targetElement = document.getElementById('menu_posts');
|
||||
if (targetElement) {
|
||||
targetElement.classList.add('current');
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
</th:block>
|
||||
<th:block layout:fragment="content" id="content">
|
||||
<section class="wrapper style1">
|
||||
<div class="container">
|
||||
<div class="row gtr-200">
|
||||
<div class="col-3 col-12-narrower">
|
||||
<div id="sidebar1">
|
||||
<section>
|
||||
<h3>Just a Subheading</h3>
|
||||
<p>Phasellus quam turpis, feugiat sit amet ornare in, hendrerit in lectus.
|
||||
Praesent semper mod quis eget mi. Etiam eu ante risus. Aliquam erat volutpat.
|
||||
Aliquam luctus et mattis lectus sit amet pulvinar. Nam turpis et nisi etiam.</p>
|
||||
<footer>
|
||||
<a href="#" class="button">Continue Reading</a>
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Another Subheading</h3>
|
||||
<ul class="links">
|
||||
<li><a href="#">Amet turpis, feugiat sit amet</a></li>
|
||||
<li><a href="#">Ornare in hendrerit lectus</a></li>
|
||||
<li><a href="#">Semper mod quis eget dolore</a></li>
|
||||
<li><a href="#">Consequat lorem phasellus</a></li>
|
||||
<li><a href="#">Amet turpis feugiat amet</a></li>
|
||||
<li><a href="#">Semper mod quisturpis nisi</a></li>
|
||||
</ul>
|
||||
<footer>
|
||||
<a href="#" class="button">More Random Links</a>
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-12-narrower imp-narrower">
|
||||
<div id="content">
|
||||
<article>
|
||||
<header>
|
||||
<h2>Two Sidebar</h2>
|
||||
<p>Yup. Two sidebars at the same time.</p>
|
||||
</header>
|
||||
|
||||
<span class="image featured"><img src="images/banner.jpg" alt="" /></span>
|
||||
|
||||
<p>Phasellus quam turpis, feugiat sit amet ornare in, hendrerit in lectus.
|
||||
Praesent semper mod quis eget mi. Etiam eu ante risus. Aliquam erat volutpat.
|
||||
Aliquam luctus et mattis lectus sit amet pulvinar. Nam turpis nisi
|
||||
consequat etiam lorem ipsum dolor sit amet nullam.</p>
|
||||
|
||||
<h3>And Yet Another Subheading</h3>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ac quam risus, at tempus
|
||||
justo. Sed dictum rutrum massa eu volutpat. Quisque vitae hendrerit sem. Pellentesque lorem felis,
|
||||
ultricies a bibendum id, bibendum sit amet nisl. Mauris et lorem quam. Maecenas rutrum imperdiet
|
||||
rhoncus dui quis euismod. Maecenas lorem tellus, congue et condimentum ac, ullamcorper non sapien.
|
||||
Donec sagittis massa et leo semper a scelerisque metus faucibus. Morbi congue mattis mi.
|
||||
Phasellus sed nisl vitae risus tristique volutpat. Cras rutrum commodo luctus.</p>
|
||||
|
||||
<p>Phasellus odio risus, faucibus et viverra vitae, eleifend ac purus. Praesent mattis, enim
|
||||
quis hendrerit porttitor, sapien tortor viverra magna, sit amet rhoncus nisl lacus nec arcu.
|
||||
Maecenas tortor mauris, consectetur pellentesque dapibus eget, tincidunt vitae arcu.
|
||||
Vestibulum purus augue, tincidunt sit amet iaculis id, porta eu purus.</p>
|
||||
</article>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3 col-12-narrower">
|
||||
<div id="sidebar2">
|
||||
|
||||
<section>
|
||||
<h3>Another Subheading</h3>
|
||||
<ul class="links">
|
||||
<li><a href="#">Amet turpis, feugiat sit amet</a></li>
|
||||
<li><a href="#">Ornare in hendrerit lectus</a></li>
|
||||
<li><a href="#">Semper mod quis eget dolore</a></li>
|
||||
<li><a href="#">Consequat lorem phasellus</a></li>
|
||||
<li><a href="#">Amet turpis feugiat amet</a></li>
|
||||
<li><a href="#">Semper mod quisturpis nisi</a></li>
|
||||
</ul>
|
||||
<footer>
|
||||
<a href="#" class="button">More Random Links</a>
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>Just a Subheading</h3>
|
||||
<p>Phasellus quam turpis, feugiat sit amet ornare in, hendrerit in lectus.
|
||||
Praesent semper mod quis eget mi. Etiam eu ante risus. Aliquam erat volutpat.
|
||||
Aliquam luctus et mattis lectus sit amet pulvinar. Nam turpis et nisi etiam.</p>
|
||||
<footer>
|
||||
<a href="#" class="button">Continue Reading</a>
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</th:block>
|
||||
</html>
|
||||
@@ -20,28 +20,31 @@
|
||||
baseData.firstPostLat = [[${srcPost.firstPostLat}]];
|
||||
document.getElementById('location_field').textContent = "Lat: " + baseData.firstPostLat + ", Lon: " + baseData.firstPostLon;
|
||||
$('#title_layer').text(baseData.title)
|
||||
var h = document.querySelector('#main_layer').getBoundingClientRect().height * 0.7
|
||||
|
||||
editor = new toastui.Editor({
|
||||
el: document.querySelector('#editor'),
|
||||
height: h+ 'px',
|
||||
height: '100%',
|
||||
width:'100%',
|
||||
viewer: true,
|
||||
usageStatistics : false,
|
||||
initialValue:baseData.content,
|
||||
theme:"dark",
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</th:block>
|
||||
<th:block layout:fragment="content" id="content">
|
||||
<section class="wrapper style2">
|
||||
<div class="container">
|
||||
<header class="major" >
|
||||
<h2 id="title_layer" th:text="${srcPost.title}">A gigantic heading you can use for whatever</h2>
|
||||
<p th:text="${#temporals.format(T(java.time.Instant).ofEpochMilli(srcPost.writeTime).atZone(T(java.time.ZoneId).systemDefault()).toLocalDateTime(), 'yyyy-MM-dd HH:mm:ss')}"></p>
|
||||
</header>
|
||||
</div>
|
||||
</section>
|
||||
<section class="wrapper style1">
|
||||
<div class="container">
|
||||
<div id="content">
|
||||
|
||||
<!-- Content -->
|
||||
|
||||
<article>
|
||||
<label id="title_layer" class="write_option" ></label>
|
||||
<div id="editor" ></div>
|
||||
<div class="write_controllbox">
|
||||
<div class="write_option btn-example" to="#popLayer1" onclick="openPopup(this)" ></div>
|
||||
@@ -50,6 +53,8 @@
|
||||
<div style="width: 15px" ></div>
|
||||
<label class="write_option" readonly id="location_field"></label>
|
||||
</div>
|
||||
<h3 id="write" th:text="${srcPost.firstAddress}"></h3>
|
||||
<h3 id="modify" th:text="${srcPost.modifyAddress}"></h3>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,14 +4,15 @@
|
||||
<div id="header">
|
||||
|
||||
<!-- Logo -->
|
||||
<h1><a href="index.html" id="logo">BUM ' <em>sPace</em></a></h1>
|
||||
<h1><a th:href="@{/}" id="logo">BUM ' <em>sPace</em></a></h1>
|
||||
|
||||
<!-- Nav -->
|
||||
<nav id="nav">
|
||||
<ul>
|
||||
<li class="current"><a href="index.html">Home</a></li>
|
||||
<li>
|
||||
<a href="#">Dropdown</a>
|
||||
<li id="menu_home" class="current"><a th:href="@{/}">Home</a></li>
|
||||
<li id="menu_posts"><a href="blog/posts">Posts</a></li>
|
||||
<li id="menu_drop">
|
||||
<a href="#">Dropdown</a>
|
||||
<ul>
|
||||
<li><a href="#">Lorem dolor</a></li>
|
||||
<li><a href="#">Magna phasellus</a></li>
|
||||
@@ -29,10 +30,10 @@
|
||||
<li><a href="#">Veroeros feugiat</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="left-sidebar">Left Sidebar</a></li>
|
||||
<li><a href="right-sidebar">Right Sidebar</a></li>
|
||||
<li><a href="two-sidebar">Two Sidebar</a></li>
|
||||
<li><a href="no-sidebar">No Sidebar</a></li>
|
||||
<li id="menu_sec"><a href="left-sidebar">Left Sidebar</a></li>
|
||||
<li id="menu_thr"><a href="right-sidebar">Right Sidebar</a></li>
|
||||
<li id="menu_four"><a href="two-sidebar">Two Sidebar</a></li>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
xmlns="http://www.w3.org/1999/html">
|
||||
<head>
|
||||
<base th:href="@{/}" />
|
||||
<th:block th:replace="~{fragments/includes :: includes}"></th:block>
|
||||
<th:block layout:fragment="head"></th:block>
|
||||
<th:block th:replace="~{fragments/title :: title}"></th:block>
|
||||
@@ -19,12 +20,12 @@
|
||||
<th:block th:replace="~{fragments/footer :: footer}"></th:block>
|
||||
</div>
|
||||
<!-- Scripts -->
|
||||
<script src="assets/js/jquery.min.js"></script>
|
||||
<script src="assets/js/jquery.dropotron.min.js"></script>
|
||||
<script src="assets/js/browser.min.js"></script>
|
||||
<script src="assets/js/breakpoints.min.js"></script>
|
||||
<script src="assets/js/util.js"></script>
|
||||
<script src="assets/js/main.js"></script>
|
||||
<script th:src="@{/assets/js/jquery.min.js}"></script>
|
||||
<script th:src="@{/assets/js/jquery.dropotron.min.js}"></script>
|
||||
<script th:src="@{/assets/js/browser.min.js}"></script>
|
||||
<script th:src="@{/assets/js/breakpoints.min.js}"></script>
|
||||
<script th:src="@{/assets/js/util.js}"></script>
|
||||
<script th:src="@{/assets/js/main.js}"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user