Browse Source

FEATURE: Do not display long TODO texts; Bump version number; Logo output

master
parent
commit
e8be103dd0
  1. 36
      pages/category.html
  2. 14
      src/main.go
  3. 6
      src/server/endpoints.go
  4. 2
      src/server/validation.go

36
pages/category.html

@ -60,8 +60,9 @@
<div> <div>
<strong>{{index .Translation "category modal todo text"}}</strong> <strong>{{index .Translation "category modal todo text"}}</strong>
<span id="modalTodoTextDisplay"></span> <span id="modalTodoTextDisplay"></span>
<input type="text" id="modalTodoTextInput" class="form-control" style="display: none;"> <!-- <input type="text" id="modalTodoTextInput" class="form-control" style="display: none;"> -->
</div> <textarea id="modalTodoTextInput" class="form-control" style="display: none;"></textarea>
</div>
<div> <div>
<strong>{{index .Translation "category modal todo created"}}</strong> <span id="modalTodoCreated"></span> <strong>{{index .Translation "category modal todo created"}}</strong> <span id="modalTodoCreated"></span>
</div> </div>
@ -114,8 +115,9 @@
<div class="row g-3 align-items-center"> <div class="row g-3 align-items-center">
<div class="col-md"> <div class="col-md">
<label for="newTodoText" class="form-label">{{index .Translation "category todo text"}}</label> <label for="newTodoText" class="form-label">{{index .Translation "category todo text"}}</label>
<input type="text" class="form-control" id="newTodoText" placeholder='{{index .Translation "category enter todo text"}}' required> <!-- <input type="text" class="form-control" id="newTodoText" placeholder='{{index .Translation "category enter todo text"}}' required> -->
</div> <textarea class="form-control" id="newTodoText" placeholder='{{index .Translation "category enter todo text"}}' required></textarea>
</div>
<div class="col-md"> <div class="col-md">
<label for="newTodoDue" class="form-label">{{index .Translation "category due date"}}</label> <label for="newTodoDue" class="form-label">{{index .Translation "category due date"}}</label>
<input type="date" class="form-control" name="newTodoDue" id="newTodoDue" required> <input type="date" class="form-control" name="newTodoDue" id="newTodoDue" required>
@ -134,8 +136,8 @@
<!-- Due --> <!-- Due -->
<table class="table table-hover" id="due-todos"> <table class="table table-hover" id="due-todos">
<thead> <thead>
<th>{{index .Translation "category image"}}</th>
<th>{{index .Translation "category todo"}}</th> <th>{{index .Translation "category todo"}}</th>
<th>{{index .Translation "category image"}}</th>
<th>{{index .Translation "category created"}}</th> <th>{{index .Translation "category created"}}</th>
<th>{{index .Translation "category due"}}</th> <th>{{index .Translation "category due"}}</th>
</thead> </thead>
@ -143,13 +145,20 @@
{{ range .Data.Todos }} {{ range .Data.Todos }}
{{ if not .IsDone }} {{ if not .IsDone }}
<tr draggable="true" id="todo-{{.ID}}" ondragstart="dragStart(event);"> <tr draggable="true" id="todo-{{.ID}}" ondragstart="dragStart(event);">
<!-- Do not display long texts fully -->
{{ if lt (len .Text) 25 }}
<td class="todo-text text-wrap text-break">{{ .Text }}</td>
{{ else }}
<td class="todo-text text-wrap text-break">{{ printf "%.25s" .Text }}......</td>
{{ end }}
{{ if not .Image }} {{ if not .Image }}
<!-- Display transparent white pixel --> <!-- Display transparent white pixel -->
<td><img class="todo-image" src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' width="64px" height="64px"></td> <td><img class="todo-image" src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' width="64px" height="64px"></td>
{{ else }} {{ else }}
<td><img class="todo-image" src='{{ printf "%s" .Image }}' width="64px" height="64px"></td> <td><img class="todo-image" src='{{ printf "%s" .Image }}' width="64px" height="64px"></td>
{{ end }} {{ end }}
<td class="todo-text text-wrap text-break">{{ .Text }}</td>
<td class="todo-created">{{ .TimeCreated }}</td> <td class="todo-created">{{ .TimeCreated }}</td>
<td class="todo-due">{{ .Due }}</td> <td class="todo-due">{{ .Due }}</td>
<td class="todo-due-unix" style="display: none;">{{ .DueUnix }}</td> <td class="todo-due-unix" style="display: none;">{{ .DueUnix }}</td>
@ -160,7 +169,7 @@
<button class="btn btn-danger" onclick="openDeleteModal('{{.ID}}');"> <button class="btn btn-danger" onclick="openDeleteModal('{{.ID}}');">
<img src='/static/images/trash3-fill.svg'> <img src='/static/images/trash3-fill.svg'>
</button> </button>
<button class="btn btn-secondary" onclick="openTodoModal('{{.ID}}', '{{.Text}}', '{{.TimeCreated}}', '{{.Due}}', null, '{{ printf "%s" .Image }}', true);"> <button class="btn btn-secondary" onclick="openTodoModal('{{.ID}}', String.raw`{{.Text}}`, '{{.TimeCreated}}', '{{.Due}}', null, '{{ printf "%s" .Image }}', true);">
<img src="/static/images/journal-arrow-up.svg"> <img src="/static/images/journal-arrow-up.svg">
</button> </button>
</td> </td>
@ -173,8 +182,8 @@
<!-- Completed --> <!-- Completed -->
<table class="table table-hover" style="display: none;" id="completed-todos"> <table class="table table-hover" style="display: none;" id="completed-todos">
<thead> <thead>
<th>{{index .Translation "category image"}}</th>
<th>{{index .Translation "category todo"}}</th> <th>{{index .Translation "category todo"}}</th>
<th>{{index .Translation "category image"}}</th>
<th>{{index .Translation "category created"}}</th> <th>{{index .Translation "category created"}}</th>
<th>{{index .Translation "category completed"}}</th> <th>{{index .Translation "category completed"}}</th>
</thead> </thead>
@ -182,20 +191,27 @@
{{ range .Data.Todos }} {{ range .Data.Todos }}
{{ if .IsDone }} {{ if .IsDone }}
<tr> <tr>
<!-- Do not display long texts fully -->
{{ if lt (len .Text) 25 }}
<td class="todo-text text-wrap text-break">{{ .Text }}</td>
{{ else }}
<td class="todo-text text-wrap text-break">{{ printf "%.25s" .Text }}......</td>
{{ end }}
{{ if not .Image }} {{ if not .Image }}
<!-- Display transparent white pixel --> <!-- Display transparent white pixel -->
<td><img src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' width="64px" height="64px"></td> <td><img src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' width="64px" height="64px"></td>
{{ else }} {{ else }}
<td><img src='{{ printf "%s" .Image }}' width="64px" height="64px"></td> <td><img src='{{ printf "%s" .Image }}' width="64px" height="64px"></td>
{{ end }} {{ end }}
<td>{{ .Text }}</td>
<td>{{ .TimeCreated }}</td> <td>{{ .TimeCreated }}</td>
<td>{{ .CompletionTime }}</td> <td>{{ .CompletionTime }}</td>
<td> <td>
<button class="btn btn-danger" onclick="deleteTodoRefresh('{{.ID}}');"> <button class="btn btn-danger" onclick="deleteTodoRefresh('{{.ID}}');">
<img src='/static/images/trash3-fill.svg'> <img src='/static/images/trash3-fill.svg'>
</button> </button>
<button class="btn btn-secondary" onclick="openTodoModal('{{.ID}}', '{{.Text}}', '{{.TimeCreated}}', '{{.Due}}', '{{.CompletionTime}}', '{{ printf "%s" .Image }}', false);"> <button class="btn btn-secondary" onclick="openTodoModal('{{.ID}}', String.raw`{{.Text}}`, '{{.TimeCreated}}', '{{.Due}}', '{{.CompletionTime}}', '{{ printf "%s" .Image }}', false);">
<img src="/static/images/journal-arrow-up.svg"> <img src="/static/images/journal-arrow-up.svg">
</button> </button>
</td> </td>

14
src/main.go

@ -28,7 +28,7 @@ import (
"path/filepath" "path/filepath"
) )
const Version string = "0.2.0" const Version string = "0.3.0"
var ( var (
printVersion *bool = flag.Bool("version", false, "Print version information and exit") printVersion *bool = flag.Bool("version", false, "Print version information and exit")
@ -42,10 +42,20 @@ var (
) )
func init() { func init() {
// Output Banner
fmt.Println(
`
v` + Version,
)
// Parse flags // Parse flags
flag.Parse() flag.Parse()
if *printVersion { if *printVersion {
fmt.Printf("dela v%s - a web TODO list\n(c) 2023 Kasyanov Nikolay Alexeyevich (Unbewohnte)\n", Version) fmt.Printf("dela v%s - a web TODO list\n(c) 2023-2025 Kasyanov Nikolay Alexeyevich (Unbewohnte)\n", Version)
os.Exit(0) os.Exit(0)
} }

6
src/server/endpoints.go

@ -599,6 +599,12 @@ func (s *Server) EndpointTodoCreate(w http.ResponseWriter, req *http.Request) {
return return
} }
// Check if text is too long or not
if uint(len(newTodo.Text)) > MaxTodoTextLength {
http.Error(w, "Text is too big!", http.StatusBadRequest)
return
}
// Add TODO to the database // Add TODO to the database
if newTodo.GroupID == 0 { if newTodo.GroupID == 0 {
http.Error(w, "No group ID was provided", http.StatusBadRequest) http.Error(w, "No group ID was provided", http.StatusBadRequest)

2
src/server/validation.go

@ -33,7 +33,7 @@ const (
MinimalPasswordLength uint = 5 MinimalPasswordLength uint = 5
MaxEmailLength uint = 60 MaxEmailLength uint = 60
MaxPasswordLength uint = 250 MaxPasswordLength uint = 250
MaxTodoLength uint = 150 MaxTodoTextLength uint = 250
) )
// Check if user is valid. Returns false and a reason-string if not // Check if user is valid. Returns false and a reason-string if not

Loading…
Cancel
Save