mirror of
https://codeberg.org/Kankys/doxa.git
synced 2026-11-11 06:44:36 +01:00
rozšíření-completeTask
This commit is contained in:
1 parent
6230b7895d
commit
b447cc8de7
6 files changed
+178
-5
No files matched your search
+99
-3
@@ -54,6 +54,10 @@ var (
|
||||
|
||||
categoryWork = lipgloss.NewStyle().
|
||||
Foreground(lipgloss.Color("#9B59B6")) // Fialová
|
||||
|
||||
completedStyle = lipgloss.NewStyle().
|
||||
Strikethrough(true).
|
||||
Foreground(lipgloss.Color("#95A5A6")) // Šedá pro splněné úkoly
|
||||
)
|
||||
|
||||
// Priority levels
|
||||
@@ -116,6 +120,7 @@ type Todo struct {
|
||||
Tags []string `json:"tags"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
ModifiedAt time.Time `json:"modified_at"`
|
||||
Completed bool `json:"completed"`
|
||||
}
|
||||
|
||||
type model struct {
|
||||
@@ -161,6 +166,7 @@ func NewModel() model {
|
||||
newTodoPriority: PriorityMedium,
|
||||
newTodoCategory: CategoryPersonal,
|
||||
}
|
||||
m.sortTodos()
|
||||
m.applyFilter()
|
||||
m.updatePlaceholders()
|
||||
return m
|
||||
@@ -170,6 +176,28 @@ func (m model) Init() tea.Cmd {
|
||||
return tea.Batch(textinput.Blink, tea.EnterAltScreen)
|
||||
}
|
||||
|
||||
func (m *model) sortTodos() {
|
||||
// Sort todos: completed ones always last, then by ID (newest first)
|
||||
for i := 0; i < len(m.todos)-1; i++ {
|
||||
for j := i + 1; j < len(m.todos); j++ {
|
||||
// If i is completed and j is not, swap
|
||||
if m.todos[i].Completed && !m.todos[j].Completed {
|
||||
m.todos[i], m.todos[j] = m.todos[j], m.todos[i]
|
||||
} else if !m.todos[i].Completed && !m.todos[j].Completed {
|
||||
// Both not completed, sort by ID (newest first)
|
||||
if m.todos[i].ID < m.todos[j].ID {
|
||||
m.todos[i], m.todos[j] = m.todos[j], m.todos[i]
|
||||
}
|
||||
} else if m.todos[i].Completed && m.todos[j].Completed {
|
||||
// Both completed, sort by ID (newest first)
|
||||
if m.todos[i].ID < m.todos[j].ID {
|
||||
m.todos[i], m.todos[j] = m.todos[j], m.todos[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *model) applyFilter() {
|
||||
if m.filterText == "" && m.currentCategoryFilter == -1 {
|
||||
m.filteredTodos = m.todos
|
||||
@@ -196,6 +224,25 @@ func (m *model) applyFilter() {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sort filtered todos: completed ones always last
|
||||
for i := 0; i < len(m.filteredTodos)-1; i++ {
|
||||
for j := i + 1; j < len(m.filteredTodos); j++ {
|
||||
// If i is completed and j is not, swap
|
||||
if m.filteredTodos[i].Completed && !m.filteredTodos[j].Completed {
|
||||
m.filteredTodos[i], m.filteredTodos[j] = m.filteredTodos[j], m.filteredTodos[i]
|
||||
} else if !m.filteredTodos[i].Completed && !m.filteredTodos[j].Completed {
|
||||
// Both not completed, sort by ID (newest first)
|
||||
if m.filteredTodos[i].ID < m.filteredTodos[j].ID {
|
||||
m.filteredTodos[i], m.filteredTodos[j] = m.filteredTodos[j], m.filteredTodos[i]
|
||||
}
|
||||
} else if m.filteredTodos[i].Completed && m.filteredTodos[j].Completed {
|
||||
// Both completed, sort by ID (newest first)
|
||||
if m.filteredTodos[i].ID < m.filteredTodos[j].ID {
|
||||
m.filteredTodos[i], m.filteredTodos[j] = m.filteredTodos[j], m.filteredTodos[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if m.cursor >= len(m.filteredTodos) {
|
||||
m.cursor = 0
|
||||
if len(m.filteredTodos) > 0 {
|
||||
@@ -492,6 +539,10 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
m.selectedTodoID = m.filteredTodos[m.cursor].ID
|
||||
m.focusIndex = 0
|
||||
}
|
||||
case "t":
|
||||
if m.state == StateViewTodos && len(m.filteredTodos) > 0 {
|
||||
m.toggleTodoCompleted()
|
||||
}
|
||||
case "+":
|
||||
if m.state == StateAddTodo || m.state == StateEditTodo {
|
||||
// Cycle priority up
|
||||
@@ -735,7 +786,12 @@ func (m model) View() string {
|
||||
if m.cursor == i {
|
||||
cursor = selectedStyle.Render("> ")
|
||||
}
|
||||
listBuilder.WriteString(fmt.Sprintf("%s%s %s %s%s\n", cursor, priorityIcon, categoryIcon, t.Title, tagStr))
|
||||
|
||||
title := t.Title
|
||||
if t.Completed {
|
||||
title = completedStyle.Render(t.Title)
|
||||
}
|
||||
listBuilder.WriteString(fmt.Sprintf("%s%s %s %s%s\n", cursor, priorityIcon, categoryIcon, title, tagStr))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -743,8 +799,8 @@ func (m model) View() string {
|
||||
m.viewport.SetContent(listBuilder.String())
|
||||
}
|
||||
|
||||
b.WriteString(fmt.Sprintf("%s | %s | %s | %s | %s | %s | %s | %s\n\n",
|
||||
tr.MenuAdd, tr.MenuEdit, tr.MenuExport, tr.MenuDelete, tr.MenuSearch, tr.MenuBrowse, tr.MenuFilter, tr.MenuLang))
|
||||
b.WriteString(fmt.Sprintf("%s | %s | %s | %s | %s | %s | %s | %s | %s\n\n",
|
||||
tr.MenuAdd, tr.MenuEdit, tr.MenuExport, tr.MenuDelete, tr.MenuSearch, tr.MenuBrowse, tr.MenuFilter, tr.MenuToggleComplete, tr.MenuLang))
|
||||
b.WriteString(tr.ListTitle + filterInfo + categoryInfo + "\n")
|
||||
|
||||
if m.ready {
|
||||
@@ -911,8 +967,10 @@ func (m *model) handleAddTodo() {
|
||||
Tags: tags,
|
||||
CreatedAt: now,
|
||||
ModifiedAt: now,
|
||||
Completed: false,
|
||||
})
|
||||
saveTodos(m.todos)
|
||||
m.sortTodos()
|
||||
m.applyFilter()
|
||||
m.statusMsg = tr.StatusSaved
|
||||
m.state = StateViewTodos
|
||||
@@ -940,6 +998,7 @@ func (m *model) handleEditTodo() {
|
||||
}
|
||||
}
|
||||
saveTodos(m.todos)
|
||||
m.sortTodos()
|
||||
m.applyFilter()
|
||||
m.statusMsg = tr.StatusEdited
|
||||
m.state = StateViewTodos
|
||||
@@ -958,9 +1017,46 @@ func (m *model) handleDeleteTodo() {
|
||||
m.todos = append(m.todos[:todoIndex], m.todos[todoIndex+1:]...)
|
||||
saveTodos(m.todos)
|
||||
}
|
||||
m.sortTodos()
|
||||
m.applyFilter()
|
||||
}
|
||||
|
||||
func (m *model) toggleTodoCompleted() {
|
||||
tr := Translations[m.lang]
|
||||
selectedID := m.filteredTodos[m.cursor].ID
|
||||
|
||||
for i, t := range m.todos {
|
||||
if t.ID == selectedID {
|
||||
m.todos[i].Completed = !m.todos[i].Completed
|
||||
m.todos[i].ModifiedAt = time.Now()
|
||||
break
|
||||
}
|
||||
}
|
||||
saveTodos(m.todos)
|
||||
m.sortTodos()
|
||||
m.applyFilter()
|
||||
|
||||
// Find the toggled todo in filtered list to update cursor
|
||||
for i, t := range m.filteredTodos {
|
||||
if t.ID == selectedID {
|
||||
m.cursor = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Find the todo to check its completed status for status message
|
||||
for _, t := range m.todos {
|
||||
if t.ID == selectedID {
|
||||
if t.Completed {
|
||||
m.statusMsg = tr.StatusCompleted
|
||||
} else {
|
||||
m.statusMsg = tr.StatusUncompleted
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func exportTodo(todos []Todo, id int64) {
|
||||
for _, todo := range todos {
|
||||
if todo.ID == id {
|
||||
|
||||
Reference in new issue
Block a user