Add Stimulus

This commit is contained in:
Andros Fenollosa 2022-04-19 21:51:43 +02:00
parent 8aa69e13b8
commit 6cdc7f43a3
15 changed files with 69 additions and 252 deletions

View File

@ -40,7 +40,7 @@ def send_page(self, page):
# Hidrate page
match page:
case "home":
update_TODO(self)
pass
def action_signup(self, data):
@ -88,29 +88,10 @@ def action_logout(self):
send_page(self, "login")
def add_lap(self):
"""Add lap to Home page"""
# Send current time to client
self.send_html({
"selector": "#laps",
"html": render_to_string("components/_lap.html", {"time": datetime.now()}),
"append": True,
})
def add_task(self, data):
"""Add task from TODO section"""
# Add task to list
self.scope["session"]["tasks"].append(data["task"])
self.scope["session"].save()
# Update task list
update_TODO(self)
def update_TODO(self):
"""Update TODO list"""
self.send_html({
"selector": "#todo",
"html": render_to_string("components/_tasks.html", {"tasks": self.scope["session"]["tasks"]}),
"append": False,
"selector": "#todo-list",
"html": render_to_string("components/_task.html", {"task": data["newTask"]}),
"append": True,
})

View File

@ -9,11 +9,6 @@ class ExampleConsumer(JsonWebsocketConsumer):
"""Event when client connects"""
# Accept the connection
self.accept()
# Make session task list
if "tasks" not in self.scope["session"]:
self.scope["session"]["tasks"] = []
self.scope["session"].save()
def disconnect(self, close_code):
"""Event when client disconnects"""
@ -38,8 +33,6 @@ class ExampleConsumer(JsonWebsocketConsumer):
actions.action_login(self, data)
case "Logout":
actions.action_logout(self)
case "Add lap":
actions.add_lap(self)
case "Add task":
actions.add_task(self, data)

View File

@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>Example website</title>
<link rel="stylesheet" href="{% static 'css/main.css' %}">
<script defer src="{% static 'js/index.js' %}"></script>
<script type="module" src="{% static 'js/main.js' %}"></script>
</head>
<body
data-host="{{ request.get_host }}"
@ -14,7 +14,7 @@
>
<div class="container">
<header>
<nav id="nav" class="nav">{% include 'components/_nav.html' %}</nav>
<nav id="nav" class="nav" data-controller="navbar">{% include 'components/_nav.html' %}</nav>
</header>
<main id="main">{% include page %}</main>
<footer class="footer">My footer</footer>

View File

@ -1,10 +1,11 @@
<ul class="nav__ul" data-controller="navbar">
<ul class="nav__ul">
{# Links always visible #}
<li>
<a
href="#"
class="nav__link nav__link--page{% if active_nav == "home" %} active{% endif %}"
data-target="home"
data-page="home"
data-action="click->navbar#changePage"
>
Home
</a>
@ -15,7 +16,8 @@
<a
href="#"
class="nav__link nav__link--page{% if active_nav == "profile" %} active{% endif %}"
data-target="profile"
data-page="profile"
data-action="click->navbar#changePage"
>
Profile
</a>
@ -35,7 +37,8 @@
<a
href="#"
class="nav__link nav__link--page{% if active_nav == "login" %} active{% endif %}"
data-target="login"
data-page="login"
data-action="click->navbar#changePage"
>
Login
</a>
@ -44,8 +47,8 @@
<a
href="#"
class="nav__link nav__link--page{% if active_nav == "signup" %} active{% endif %}"
data-target="signup"
data-action="click->message#displayUpdateForm"
data-page="signup"
data-action="click->navbar#changePage"
>
Signup
</a>

View File

@ -0,0 +1 @@
<li>{{ task }}</li>

View File

@ -1,3 +0,0 @@
{% for task in tasks %}
<li>{{ task }}</li>
{% endfor %}

View File

@ -2,16 +2,9 @@
<h1>Welcome to an example of browsing with WebSockets over the Wire</h1>
<p>You will be able to experience a simple structure with a registration, a login and a private page.</p>
</section>
<section>
<h2>Laps</h2>
<p>
<button id="add-lap">Add lap</button>
</p>
<ul id="laps"></ul>
</section>
<section>
<section data-controller="todo">
<h2>TODO</h2>
<input type="text" id="task">
<button id="add-task">Add task</button>
<ul id="todo"></ul>
<input type="text" data-todo-target="task">
<button data-action="click->todo#addNewTask">Add task</button>
<ul id="todo-list"></ul>
</section>

View File

@ -1,28 +0,0 @@
import { Controller } from "../vendors/stimulus.js"
import { sendData } from "../webSocketsCli.js"
export default class extends Controller {
static targets = [ "author", "text" ]
/**
* Send new message
* @param {Event} event
* @return {void}
*/
add(event) {
event.preventDefault();
// Prepare the information we will send
const newData = {
"action": "add message",
"data": {
"author": this.authorTarget.value,
"text": this.textTarget.value
}
};
// Send the data to the server
sendData(newData, window.myWebSocket);
// Clear message form
this.textTarget.value = "";
}
}

View File

@ -1,116 +0,0 @@
import { Controller } from "../vendors/stimulus.js"
import { sendData } from "../webSocketsCli.js"
export default class extends Controller {
static targets = [ "item", "paginator" ]
connect() {
this.enableInfiniteScroll();
}
/*
FUNCTIONS
*/
/**
* Switches to the next page when the last message is displayed.
*/
enableInfiniteScroll() {
const lastMessage = this.itemTargets.at(-1);
// Turn the page when the last message is displayed.
const observerLastMessage = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
if (!this.isLastPage()) this.goToNextPage();
}
});
});
observerLastMessage.observe(lastMessage);
}
/**
* Get current page stored in #paginator as dataset
* @returns {number}
*/
getCurrentPage() {
return parseInt(this.paginatorTarget.dataset.page);
}
/**
* Check if we are on the last page
* @returns {boolean}
*/
isLastPage() {
return parseInt(this.paginatorTarget.dataset.totalPages) === this.getCurrentPage();
}
/**
* Switch to the next page
* @param {Event} event
* @return {void}
*/
goToNextPage(event) {
// Prepare the information we will send
const newData = {
"action": "list messages",
"data": {
"page": this.getCurrentPage() + 1,
}
};
// Send the data to the server
sendData(newData, myWebSocket);
}
/**
* Displays the update form
* @param {Event} event
* @return {void}
*/
displayUpdateForm(event) {
const message = {
"action": "open edit page",
"data": {
"id": event.target.dataset.id
}
};
sendData(message, window.myWebSocket);
}
/**
* Update message
* @param {Event} event
* @return {void}
*/
updateMessage(event) {
event.preventDefault();
const message = {
"action": "update message",
"data": {
"id": event.target.dataset.id,
"author": event.target.querySelector("#message-form__author--update").value,
"text": event.target.querySelector("#message-form__text--update").value
}
};
sendData(message, myWebSocket);
}
/**
* Delete message
* @param {Event} event
* @return {void}
*/
deleteMessage(event) {
const message = {
"action": "delete message",
"data": {
"id": event.target.dataset.id
}
};
sendData(message, window.myWebSocket);
}
}

View File

@ -1,28 +0,0 @@
import { Controller } from "../vendors/stimulus.js"
import { sendData } from "../webSocketsCli.js"
export default class extends Controller {
static targets = [ "page" ]
/**
* Send new message
* @param {Event} event
* @return {void}
*/
add(event) {
event.preventDefault();
// Prepare the information we will send
const newData = {
"action": "add message",
"data": {
"author": this.authorTarget.value,
"text": this.textTarget.value
}
};
// Send the data to the server
sendData(newData, window.myWebSocket);
// Clear message form
this.textTarget.value = "";
}
}

View File

@ -0,0 +1,22 @@
import { Controller } from "../vendors/stimulus.js"
import { sendData } from "../webSocketsCli.js"
export default class extends Controller {
static targets = [ "page" ]
/**
* Send message to update page
* @param {Event} event
* @return {void}
*/
changePage(event) {
event.preventDefault();
sendData({
action: 'Change page',
data: {
page: event.target.dataset.page
}
}, window.myWebSocket);
}
}

View File

@ -0,0 +1,22 @@
import { Controller } from "../vendors/stimulus.js"
import { sendData } from "../webSocketsCli.js"
export default class extends Controller {
static targets = [ "task" ]
/**
* Render new task
* @return {void}
*/
addNewTask() {
sendData({
action: 'Add task',
data: {
newTask: this.taskTarget.value
}
}, window.myWebSocket);
// Clean input
this.taskTarget.value = '';
}
}

View File

@ -1,25 +0,0 @@
import { Controller } from "../vendors/stimulus.js"
import { sendData } from "../webSocketsCli.js"
export default class extends Controller {
static targets = [ "author", "text" ]
/**
* Update message
* @param {Event} event
* @return {void}
*/
update(event) {
event.preventDefault();
const message = {
"action": "update message",
"data": {
"id": event.target.dataset.id,
"author": this.authorTarget.value,
"text": this.textTarget.value
}
};
sendData(message, myWebSocket);
}
}

View File

@ -1,6 +1,7 @@
import {connect, startEvents} from './webSocketsCli.js';
import { Application } from "./vendors/stimulus.js"
import navbarController from "./controllers/navbar.js"
import navbarController from "./controllers/navbar_controller.js"
import todoController from "./controllers/todo_controller.js"
/*
INITIALIZATION
*/
@ -12,4 +13,5 @@ startEvents();
// Stimulus
window.Stimulus = Application.start();
// Register all controllers
Stimulus.register("navbar", navbarController);
Stimulus.register("navbar", navbarController);
Stimulus.register("todo", todoController);

View File

@ -7,7 +7,7 @@
* @param {string} url - WebSockets server url
* @return {WebSocket}
*/
export function connect(url=`${document.body.dataset.scheme === 'http' ? 'ws' : 'wss'}://${ document.body.dataset.host }/ws/social-network/`) {
export function connect(url=`${document.body.dataset.scheme === 'http' ? 'ws' : 'wss'}://${ document.body.dataset.host }/ws/example/`) {
window.myWebSocket = new WebSocket(url);
return window.myWebSocket;
}