Skip to content

Commit

Permalink
feat: add upper limit to number of tasks that can be stored
Browse files Browse the repository at this point in the history
Add dependabot config.
  • Loading branch information
dhth committed Jul 9, 2024
1 parent 853e1b9 commit ddfc6f5
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 38 deletions.
26 changes: 26 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"
time: "16:00"
reviewers:
- "dhth"
labels:
- "dependencies"
commit-message:
prefix: "chore"
include: "scope"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
time: "16:00"
reviewers:
- "dhth"
labels:
- "dependencies"
commit-message:
prefix: "chore"
include: "scope"
47 changes: 32 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,21 @@ interface that can be managed entirely via the keyboard.
💾 Installation
---

**homebrew**:

```sh
brew install dhth/tap/omm
```

**go**:

```sh
go install github.com/dhth/omm@latest
```

Or get the binaries directly from a
[release](https://github.com/dhth/omm/releases).

⚡️ Usage
---

Expand All @@ -47,6 +56,10 @@ go install github.com/dhth/omm@latest
- view archived tasks
- delete a task

![Screen 1](https://tools.dhruvs.space/images/omm/omm-1.png)

![Screen 2](https://tools.dhruvs.space/images/omm/omm-2.png)

#### Tweaking the TUI

The list colors and the task list title can be changed via CLI flags.
Expand All @@ -70,6 +83,9 @@ Assemble ACME jet-propelled pogo stick
EOF
```

Tip: Vim users can import tasks into omm by making a visual selection and
running `:'<,'>!omm import<CR>`.

### Adding a single task

When an argument is passed to `omm`, it saves it as a task, instead of opening
Expand All @@ -88,25 +104,26 @@ Tasks can be outputted to `stdout` using the `tasks` subcommand.
omm tasks
```

Screenshots
---

![Screen 1](https://tools.dhruvs.space/images/omm/omm-1.png)

![Screen 2](https://tools.dhruvs.space/images/omm/omm-2.png)

⌨️ Keymaps
---

```text
j/↓: move cursor down k/↑: move cursor up
o: add task above cursor a: add task below cursor
O: add task at the beginning of list A: add task at the end of list
J: move task one position down K: move task one position up
[2-9]: move task at index "x" to top of list ⏎: move task on cursor to top of list
ctrl+d: archive/unarchive task ctrl+x: delete task
g: go to top of list G: go to end of list
tab: move between views q/esc: go back/quit
j/↓: move cursor down
k/↑: move cursor up
o/a: add task below cursor
O: add task above cursor
I: add task at the top
A: add task at the end
J: move task one position down
K: move task one position up
[2-9]: move task at index "x" to top
⏎: move task to the top
ctrl+d: archive/unarchive task
ctrl+x: delete task
g: go to the top
G: go to the end
tab: move between views
q/esc: go back/quit
```

Acknowledgements
Expand Down
23 changes: 22 additions & 1 deletion cmd/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,38 @@ package cmd

import (
"database/sql"
"fmt"
"time"

pers "github.com/dhth/omm/internal/persistence"
)

var (
importWillExceedTaskLimitErr = fmt.Errorf("Import will exceed maximum number of tasks allowed, which is %d. Archive/Delete tasks that are not active using ctrl+d/ctrl+x.", pers.TaskNumLimit)
)

func importTask(db *sql.DB, taskSummary string) error {
numTasks, err := pers.FetchNumActiveTasksFromDB(db)
if err != nil {
return err
}
if numTasks+1 > pers.TaskNumLimit {
return importWillExceedTaskLimitErr
}

now := time.Now()
return pers.ImportTaskIntoDB(db, taskSummary, true, now, now)
}

func importTasks(db *sql.DB, taskSummaries []string) error {
now := time.Now()
numTasks, err := pers.FetchNumActiveTasksFromDB(db)
if err != nil {
return err
}
if numTasks+len(taskSummaries) > pers.TaskNumLimit {
return importWillExceedTaskLimitErr
}

now := time.Now().AddDate(-1, 0, 0)
return pers.ImportTasksIntoDB(db, taskSummaries, true, now, now)
}
9 changes: 4 additions & 5 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"runtime"
"strings"

pers "github.com/dhth/omm/internal/persistence"
"github.com/dhth/omm/internal/ui"
"github.com/dhth/omm/internal/utils"
"github.com/spf13/cobra"
Expand All @@ -22,8 +23,6 @@ const (
repoIssuesUrl = "https://github.com/dhth/omm/issues"
defaultDataDir = ".local/share"
dbFileName = "omm/omm.db"
maxTaskImportCount = 1000
printTasksLimit = 50
printTasksDefault = 20
taskListTitleMaxLen = 8
)
Expand Down Expand Up @@ -155,8 +154,8 @@ var importCmd = &cobra.Command{

scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
if taskCounter > maxTaskImportCount {
die("Max number of tasks that can be imported at a time: %d", maxTaskImportCount)
if taskCounter > pers.TaskNumLimit {
die("Max number of tasks that can be imported at a time: %d", pers.TaskNumLimit)
}

line := scanner.Text()
Expand Down Expand Up @@ -231,7 +230,7 @@ func init() {
rootCmd.Flags().StringVar(&archivedTaskListColor, "atl-color", ui.ArchivedTLColor, "hex color used for the archived tasks list")
rootCmd.Flags().StringVar(&taskListTitle, "title", ui.TaskListDefaultTitle, fmt.Sprintf("title of the task list, will trim till %d chars", taskListTitleMaxLen))

tasksCmd.Flags().Uint8VarP(&printTasksNum, "num", "n", printTasksDefault, fmt.Sprintf("number of tasks to print; maximum allowed: %d", printTasksLimit))
tasksCmd.Flags().Uint8VarP(&printTasksNum, "num", "n", printTasksDefault, "number of tasks to print")

rootCmd.AddCommand(importCmd)
rootCmd.AddCommand(tasksCmd)
Expand Down
22 changes: 21 additions & 1 deletion internal/persistence/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,26 @@ import (
"github.com/dhth/omm/internal/types"
)

const (
TaskNumLimit = 300
)

func FetchNumActiveTasksFromDB(db *sql.DB) (int, error) {

row := db.QueryRow(`
SELECT json_array_length(sequence) AS num_tasks
FROM task_sequence where id=1;
`)

var numTasks int
err := row.Scan(&numTasks)
if err != nil {
return -1, err
}

return numTasks, nil
}

func UpdateTaskSequenceInDB(db *sql.DB, sequence []uint64) error {

sequenceJson, err := json.Marshal(sequence)
Expand Down Expand Up @@ -261,7 +281,7 @@ JOIN json_each(s.sequence) j ON CAST(j.value AS INTEGER) = t.id
JOIN task t ON t.id = j.value
ORDER BY j.key
LIMIT ?;
`, limit)
`, limit)
if err != nil {
return nil, err
}
Expand Down
16 changes: 8 additions & 8 deletions internal/ui/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package ui
var helpMsg = `omm ("on-my-mind") is a keyboard-driven task manager for the command line.
[Keymaps]
j/↓: move cursor down k/↑: move cursor up
o: add task above cursor a: add task below cursor
O: add task at the beginning of list A: add task at the end of list
J: move task one position down K: move task one position up
[2-9]: move task at index "x" to top of list ⏎: move task on cursor to top of list
ctrl+d: archive/unarchive task ctrl+x: delete task
g: go to top of list G: go to end of list
tab: move between views q/esc: go back/quit
j/↓: move cursor down k/↑: move cursor up
o/a: add task below cursor O: add task above cursor
I: add task at the top A: add task at the end
J: move task one position down K: move task one position up
[2-9]: move task at index "x" to top ⏎: move task to the top
ctrl+d: archive/unarchive task ctrl+x: delete task
g: go to the top G: go to the end
tab: move between views q/esc: go back/quit
`
8 changes: 4 additions & 4 deletions internal/ui/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
pers "github.com/dhth/omm/internal/persistence"
"github.com/dhth/omm/internal/types"
"github.com/dhth/omm/internal/utils"
)

type itemDelegate struct {
Expand All @@ -31,7 +31,7 @@ func (d itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list
start, _ := m.Paginator.GetSliceBounds(index)
si := (index - start) % m.Paginator.PerPage

str := fmt.Sprintf("[%d]\t%s", si+1, utils.RightPadTrim(i.Summary, 80, true))
str := fmt.Sprintf("[%d]\t%s", si+1, i.Summary)

fn := itemStyle.Render
if index == m.Index() {
Expand All @@ -45,8 +45,8 @@ func (d itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list

func (m model) Init() tea.Cmd {
return tea.Batch(
fetchTasks(m.db, true, 50),
fetchTasks(m.db, false, 50),
fetchTasks(m.db, true, pers.TaskNumLimit),
fetchTasks(m.db, false, pers.TaskNumLimit),
hideHelp(time.Minute*1),
)
}
Expand Down
35 changes: 32 additions & 3 deletions internal/ui/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ import (

"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
pers "github.com/dhth/omm/internal/persistence"
"github.com/dhth/omm/internal/types"
)

const (
noSpaceAvailableMsg = "Task list is at capacity. Archive/delete tasks using ctrl+d/ctrl+x."
)

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
var cmds []tea.Cmd
Expand Down Expand Up @@ -110,35 +115,50 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmd = m.updateTaskSequence()
cmds = append(cmds, cmd)

case "O":
case "I":
if m.activeView == taskEntryView {
break
}

if !m.isSpaceAvailable() {
m.message = noSpaceAvailableMsg
break
}

m.taskIndex = 0
m.taskInput.Reset()
m.taskInput.Focus()
m.taskChange = taskInsert
m.activeView = taskEntryView
return m, tea.Batch(cmds...)

case "o":
case "O":
if m.activeView == taskEntryView {
break
}

if !m.isSpaceAvailable() {
m.message = noSpaceAvailableMsg
break
}

m.taskIndex = m.taskList.Index()
m.taskInput.Reset()
m.taskInput.Focus()
m.taskChange = taskInsert
m.activeView = taskEntryView
return m, tea.Batch(cmds...)

case "a":
case "a", "o":
if m.activeView == taskEntryView {
break
}

if !m.isSpaceAvailable() {
m.message = noSpaceAvailableMsg
break
}

if len(m.taskList.Items()) == 0 {
m.taskIndex = 0
} else {
Expand All @@ -155,6 +175,11 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
break
}

if !m.isSpaceAvailable() {
m.message = noSpaceAvailableMsg
break
}

m.taskIndex = len(m.taskList.Items())
m.taskInput.Reset()
m.taskInput.Focus()
Expand Down Expand Up @@ -443,3 +468,7 @@ func (m model) updateTaskSequence() tea.Cmd {

return updateTaskSequence(m.db, sequence)
}

func (m model) isSpaceAvailable() bool {
return len(m.taskList.Items()) < pers.TaskNumLimit
}
2 changes: 1 addition & 1 deletion internal/ui/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (m model) View() string {
if len(m.taskList.Items()) > 0 {
content = m.taskList.View()
} else {
content = taskInputFormStyle.Render(" No items. Press a to add one.")
content = taskInputFormStyle.Render(" No items. Press o to add one.")
}
case archivedTaskListView:
header = m.atlTitleStyle.Render("archived")
Expand Down

0 comments on commit ddfc6f5

Please sign in to comment.