diff --git a/khaikang/settings.py b/khaikang/settings.py index e2cf6d6..e6d3f30 100644 --- a/khaikang/settings.py +++ b/khaikang/settings.py @@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/4.1/ref/settings/ """ from pathlib import Path +import os # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -117,7 +118,8 @@ USE_TZ = True # https://docs.djangoproject.com/en/4.1/howto/static-files/ STATIC_URL = 'static/' -STATIC_ROOT = '/home/kiantin1/public_html/khaikang/static/' +STATICFILES_DIRS= [os.path.join(BASE_DIR, 'static')] # test only +# STATIC_ROOT = '/home/kiantin1/public_html/khaikang/static/' deploy only # Default primary key field type # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field diff --git a/khaikang/urls.py b/khaikang/urls.py index f3df2dc..4a309eb 100644 --- a/khaikang/urls.py +++ b/khaikang/urls.py @@ -28,3 +28,4 @@ urlpatterns = [ path('api/get_latest_posts', views.api_get_latest_posts), path('api/get_previous_posts', views.api_get_previous_posts), ] + diff --git a/static/admin/css/dark_mode.css b/static/admin/css/dark_mode.css new file mode 100644 index 0000000..547717c --- /dev/null +++ b/static/admin/css/dark_mode.css @@ -0,0 +1,33 @@ +@media (prefers-color-scheme: dark) { + :root { + --primary: #264b5d; + --primary-fg: #f7f7f7; + + --body-fg: #eeeeee; + --body-bg: #121212; + --body-quiet-color: #e0e0e0; + --body-loud-color: #ffffff; + + --breadcrumbs-link-fg: #e0e0e0; + --breadcrumbs-bg: var(--primary); + + --link-fg: #81d4fa; + --link-hover-color: #4ac1f7; + --link-selected-fg: #6f94c6; + + --hairline-color: #272727; + --border-color: #353535; + + --error-fg: #e35f5f; + --message-success-bg: #006b1b; + --message-warning-bg: #583305; + --message-error-bg: #570808; + + --darkened-bg: #212121; + --selected-bg: #1b1b1b; + --selected-row: #00363a; + + --close-button-bg: #333333; + --close-button-hover-bg: #666666; + } + } diff --git a/static/admin/js/filters.js b/static/admin/js/filters.js new file mode 100644 index 0000000..ba691ac --- /dev/null +++ b/static/admin/js/filters.js @@ -0,0 +1,30 @@ +/** + * Persist changelist filters state (collapsed/expanded). + */ +'use strict'; +{ + // Init filters. + let filters = JSON.parse(sessionStorage.getItem('django.admin.filtersState')); + + if (!filters) { + filters = {}; + } + + Object.entries(filters).forEach(([key, value]) => { + const detailElement = document.querySelector(`[data-filter-title='${key}']`); + + // Check if the filter is present, it could be from other view. + if (detailElement) { + value ? detailElement.setAttribute('open', '') : detailElement.removeAttribute('open'); + } + }); + + // Save filter state when clicks. + const details = document.querySelectorAll('details'); + details.forEach(detail => { + detail.addEventListener('toggle', event => { + filters[`${event.target.dataset.filterTitle}`] = detail.open; + sessionStorage.setItem('django.admin.filtersState', JSON.stringify(filters)); + }); + }); +} diff --git a/static/timeline.js b/static/timeline.js new file mode 100644 index 0000000..af197b2 --- /dev/null +++ b/static/timeline.js @@ -0,0 +1,178 @@ + +timezoneChangingOne = (x)=>{var date= new Date(x.innerHTML); + var year = date.getFullYear().toString(); + var month = (date.getMonth()+1).toString().padStart(2, '0'); + var day = date.getDate().toString().padStart(2, '0'); + var hour = date.getHours().toString().padStart(2, '0'); + var min = date.getMinutes().toString().padStart(2, '0'); + var sec = date.getSeconds().toString().padStart(2, '0'); + local_date_string = `${year}-${month}-${day} ${hour}:${min}:${sec}`; + x.innerHTML=local_date_string;} + +function timezoneChanging(){ +document.querySelectorAll(".post-time").forEach( +x => timezoneChangingOne(x) + ); +} + + + +$name = (x) => document.getElementsByName(x); +$ = (x) => document.getElementById(x); +var httpRequest; +$("submit_post").addEventListener('click', make_req); + +async function make_req() { + +post_text = $('post_text').value; +post_privilage = $('privil_choosing').value; + +if (post_text != ""){ + +await fetch('/api/post', { +method: 'POST', +headers: { +"X-CSRFToken": "{{ csrf_token }}", +'Content-Type': 'application/json', +}, +body: JSON.stringify({ +"privilage" : post_privilage, +"text": post_text, +}) + +}).then(response => {if (response.ok == true) +{$('post_text').value = ""; +getLatestPosts(); // wait for a moment then get latest posts +}} + +); +} + + + +} + +function auto_expand(element) { +element.style.height = 6+"em"; +element.style.height = (element.scrollHeight)+"px"; +} + +timezoneChanging(); + +function adjust_post_text(){ +var post_text = $("post_text"); +post_text.style.height = 6+"em"; +post_text.style.height = (post_text.scrollHeight)+"px"; +} + + +async function getRecentPostsCounter(){ +latest_time_string = $("latest_time").innerHTML; +await fetch('/api/get_recent_posts_counter', { +method: 'POST', +headers: { +"X-CSRFToken": "{{ csrf_token }}", +'Content-Type': 'application/json', +}, +body: JSON.stringify({ +"latest_time" : latest_time_string, +}) + +}).then(response => response.json()) +.then(the_json => {console.log(the_json);let newer_posts_num = the_json['newer_posts_num']; +if (newer_posts_num == 1) +{ $("new_post_notifier").style.display = "block"; +$("new_post_notifier").innerHTML = `1 new post`} +if (newer_posts_num > 1) +{ $("new_post_notifier").style.display = "block"; +$("new_post_notifier").innerHTML = `${newer_posts_num} new posts`} }); + +} + +var intervalID = window.setInterval(getRecentPostsCounter, 20000); + +function appendPostToTheEnd(post){ +var public_tl = $("public_timeline"); +var new_div = createPostDiv(post); + + +public_tl.insertBefore(new_div, $('previous_post_loader')); +} + +async function getPreviousPosts(){ +var new_oldest_time; +oldest_time_string = $("oldest_time").innerHTML; +await fetch('/api/get_previous_posts', { +method: 'POST', +headers: { +"X-CSRFToken": "{{ csrf_token }}", +'Content-Type': 'application/json', +}, +body: JSON.stringify({ +"oldest_time" : oldest_time_string, +}) }).then(response => response.json()) +.then(item => {new_oldest_time_raw = item['oldest_time']; + new_oldest_time = new_oldest_time_raw.substring(0,10) + " " + new_oldest_time_raw.substring(11,26) + "+0000"; + return item['older_posts'];}) +.then(posts => {if (posts.length == 0) + {$('previous_post_loader').style.display = 'none';} + else{posts.forEach(post => appendPostToTheEnd(post)); + $('oldest_time').innerHTML = new_oldest_time;}}) +} + + +async function getLatestPosts(){ +latest_time_string = $("latest_time").innerHTML; +await fetch('/api/get_latest_posts', { +method: 'POST', +headers: { +"X-CSRFToken": "{{ csrf_token }}", +'Content-Type': 'application/json', +}, +body: JSON.stringify({ +"latest_time" : latest_time_string, +}) }).then(response => response.json()) +.then(item => item['newer_posts']) +.then(posts => {posts.forEach(post => addPostToTheBeginning(post)); +$('new_post_notifier').style.display = "none"; +var nowTime = new Date(); +var nowTimeString = nowTime.toISOString(); +$("latest_time").innerHTML = nowTimeString.substring(0,10) + " " + nowTimeString.substring(11,23) + "000+0000"; }); +} + +function createPostDiv(post){ + +var new_div = document.createElement("div"); +new_div.id = `post-${post.id}`; +new_div.className = "post"; +post_text_replaced = post.text.replace(/(\r\n|\n\r|\r|\n)/g, "
" ); +console.log(post_text_replaced); +new_div.innerHTML = `${post.poster_shown_name} +at ${post.post_time}
+${post_text_replaced}
+↩ī¸ +- 🔁 +- ⭐`; + +new_div_timestamp = new_div.getElementsByClassName('post-time')[0]; + +timezoneChangingOne(new_div_timestamp); + +return new_div; +} + +function addPostToTheBeginning(post){ +var public_tl = $("public_timeline"); +var new_div = createPostDiv(post); + + +public_tl.insertBefore(new_div, $('latest_time').nextSibling); + +} + +$("new_post_notifier").addEventListener('click', getLatestPosts); +$("previous_post_loader").addEventListener('click', getPreviousPosts); + + + +adjust_post_text(); \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index 0324c3a..4a39a62 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,7 +1,12 @@ {% extends "base_generic.html" %} - +{% load static %} {% load tz %} + {% get_current_timezone as TIME_ZONE %} +{% block headbar %} +{{ request.user.shown_name }} (My timeline) - Configs - Log out +{% endblock %} + {% block content %}
{% csrf_token %} @@ -31,8 +36,8 @@ {% for public_post in public_timeline_list %} -
{{public_post.poster.shown_name}} - at {{public_post.post_time|date:"Y-m-d H:i:s.u"}}+0000
+
{{public_post.poster.shown_name}} + at {{public_post.post_time|date:"Y-m-d H:i:s.u"}}+0000
{{public_post.text|linebreaksbr}}
↩ī¸ - 🔁 @@ -45,185 +50,9 @@
- {% endblock %} \ No newline at end of file