Added Task Export (to clipboard) feature. Closes #17
This commit is contained in:
@@ -35,6 +35,7 @@
|
|||||||
- [x] Set Task due date with quick input buttons (today, +1 day, -1 day)
|
- [x] Set Task due date with quick input buttons (today, +1 day, -1 day)
|
||||||
- [x] Update Task Title
|
- [x] Update Task Title
|
||||||
- [x] Tasklist items should indicate status (done, pending, overdue) using colors
|
- [x] Tasklist items should indicate status (done, pending, overdue) using colors
|
||||||
|
- [x] Export Tasks (Copy title, dueDate and description to clipboard as Markdown)
|
||||||
- [ ] Pin Tasks
|
- [ ] Pin Tasks
|
||||||
- [x] Shortcut for Adding new Project and Task
|
- [x] Shortcut for Adding new Project and Task
|
||||||
- [x] Global shortcuts for jumping to Projects or Tasks panel anytime
|
- [x] Global shortcuts for jumping to Projects or Tasks panel anytime
|
||||||
@@ -101,6 +102,7 @@ In case writing in a text input (e,g, new project/task, due date), you have to `
|
|||||||
| Task Detail | `e` | Activate note editor for modification |
|
| Task Detail | `e` | Activate note editor for modification |
|
||||||
| Task Detail | `v` | Edit task details in external editor (default `vim`) |
|
| Task Detail | `v` | Edit task details in external editor (default `vim`) |
|
||||||
| Task Detail | `r` | Rename Task Title |
|
| Task Detail | `r` | Rename Task Title |
|
||||||
|
| Task Detail | `x` | Export Task to clipboard |
|
||||||
| Active Note Editor | `Esc` | Deactivate note editor and save content |
|
| Active Note Editor | `Esc` | Deactivate note editor and save content |
|
||||||
|
|
||||||
**Tips about using shortcuts efficiently:**
|
**Tips about using shortcuts efficiently:**
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/atotto/clipboard"
|
||||||
"github.com/gdamore/tcell/v2"
|
"github.com/gdamore/tcell/v2"
|
||||||
"github.com/pgavlin/femto"
|
"github.com/pgavlin/femto"
|
||||||
"github.com/pgavlin/femto/runtime"
|
"github.com/pgavlin/femto/runtime"
|
||||||
@@ -49,7 +51,7 @@ func NewTaskDetailPane(taskRepo repository.TaskRepository) *TaskDetailPane {
|
|||||||
toggleHint := tview.NewTextView().SetTextColor(tcell.ColorDimGray).SetText("<space> to toggle")
|
toggleHint := tview.NewTextView().SetTextColor(tcell.ColorDimGray).SetText("<space> to toggle")
|
||||||
pane.taskStatusToggle.SetSelectedFunc(pane.toggleTaskStatus)
|
pane.taskStatusToggle.SetSelectedFunc(pane.toggleTaskStatus)
|
||||||
|
|
||||||
pane.editorHint = tview.NewTextView().SetText(" e to edit, ↓↑ to scroll").SetTextColor(tcell.ColorDimGray)
|
pane.editorHint = tview.NewTextView().SetText(" e = edit, v = external, ↓↑ = scroll").SetTextColor(tcell.ColorDimGray)
|
||||||
|
|
||||||
// Prepare static (no external interaction) elements
|
// Prepare static (no external interaction) elements
|
||||||
editorLabel := tview.NewFlex().
|
editorLabel := tview.NewFlex().
|
||||||
@@ -58,7 +60,7 @@ func NewTaskDetailPane(taskRepo repository.TaskRepository) *TaskDetailPane {
|
|||||||
editorHelp := tview.NewFlex().
|
editorHelp := tview.NewFlex().
|
||||||
AddItem(pane.editorHint, 0, 1, false).
|
AddItem(pane.editorHint, 0, 1, false).
|
||||||
AddItem(tview.NewTextView().SetTextAlign(tview.AlignRight).
|
AddItem(tview.NewTextView().SetTextAlign(tview.AlignRight).
|
||||||
SetText("syntax:markdown theme:monakai").
|
SetText("syntax:markdown (monakai)").
|
||||||
SetTextColor(tcell.ColorDimGray), 0, 1, false)
|
SetTextColor(tcell.ColorDimGray), 0, 1, false)
|
||||||
|
|
||||||
pane.
|
pane.
|
||||||
@@ -78,11 +80,25 @@ func NewTaskDetailPane(taskRepo repository.TaskRepository) *TaskDetailPane {
|
|||||||
return &pane
|
return &pane
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (td *TaskDetailPane) Export() {
|
||||||
|
var content bytes.Buffer
|
||||||
|
|
||||||
|
content.WriteString("# " + td.task.Title + " \n")
|
||||||
|
if td.taskDate.GetText() != "" {
|
||||||
|
content.WriteString("\n> Due Date: " + td.taskDate.GetText() + " \n")
|
||||||
|
}
|
||||||
|
content.WriteString("\n" + td.task.Details + " \n")
|
||||||
|
|
||||||
|
clipboard.WriteAll(content.String())
|
||||||
|
app.SetFocus(td)
|
||||||
|
statusBar.showForSeconds("Task copyed. Try Pasting anywhere.", 5)
|
||||||
|
}
|
||||||
|
|
||||||
func (td *TaskDetailPane) makeDateRow() *tview.Flex {
|
func (td *TaskDetailPane) makeDateRow() *tview.Flex {
|
||||||
|
|
||||||
td.taskDate = makeLightTextInput("yyyy-mm-dd").
|
td.taskDate = makeLightTextInput("yyyy-mm-dd").
|
||||||
SetLabel("Set:").
|
SetLabel("Set:").
|
||||||
SetLabelColor(tcell.ColorGray).
|
SetLabelColor(tcell.ColorWhiteSmoke).
|
||||||
SetFieldWidth(12).
|
SetFieldWidth(12).
|
||||||
SetDoneFunc(func(key tcell.Key) {
|
SetDoneFunc(func(key tcell.Key) {
|
||||||
switch key {
|
switch key {
|
||||||
@@ -220,7 +236,7 @@ func (td *TaskDetailPane) activateEditor() {
|
|||||||
func (td *TaskDetailPane) deactivateEditor() {
|
func (td *TaskDetailPane) deactivateEditor() {
|
||||||
td.taskDetailView.Readonly = true
|
td.taskDetailView.Readonly = true
|
||||||
td.taskDetailView.SetBorderColor(tcell.ColorLightSlateGray)
|
td.taskDetailView.SetBorderColor(tcell.ColorLightSlateGray)
|
||||||
td.editorHint.SetText(" e to edit, ↓↑ to scroll")
|
td.editorHint.SetText(" e = edit, v = external, ↓↑ = scroll")
|
||||||
app.SetFocus(td)
|
app.SetFocus(td)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +275,6 @@ func (td *TaskDetailPane) editInExternalEditor() {
|
|||||||
td.SetTask(td.task)
|
td.SetTask(td.task)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO: Mouse events not being captured after returning from Suspend - fix it
|
|
||||||
app.EnableMouse(true)
|
app.EnableMouse(true)
|
||||||
|
|
||||||
_ = os.Remove(tmpFileName)
|
_ = os.Remove(tmpFileName)
|
||||||
@@ -310,6 +325,9 @@ func (td *TaskDetailPane) handleShortcuts(event *tcell.EventKey) *tcell.EventKey
|
|||||||
case ' ':
|
case ' ':
|
||||||
td.toggleTaskStatus()
|
td.toggleTaskStatus()
|
||||||
return nil
|
return nil
|
||||||
|
case 'x':
|
||||||
|
td.Export()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ func NewTaskDetailHeader(taskRepo repository.TaskRepository) *TaskDetailHeader {
|
|||||||
buttons := tview.NewFlex().
|
buttons := tview.NewFlex().
|
||||||
AddItem(tview.NewTextView().SetTextColor(tcell.ColorDimGray).SetText("r = Rename"), 0, 1, false).
|
AddItem(tview.NewTextView().SetTextColor(tcell.ColorDimGray).SetText("r = Rename"), 0, 1, false).
|
||||||
AddItem(blankCell, 0, 1, false).
|
AddItem(blankCell, 0, 1, false).
|
||||||
AddItem(makeButton("rename", func() { header.ShowRename() }), 8, 0, false)
|
AddItem(makeButton("[::ub]r[::-]ename", func() { header.ShowRename() }), 8, 0, false).
|
||||||
|
AddItem(blankCell, 1, 0, false).
|
||||||
|
AddItem(makeButton("e[::ub]x[::-]port", func() { taskDetailPane.Export() }), 8, 0, false)
|
||||||
|
|
||||||
header.
|
header.
|
||||||
AddItem(header.pages, 1, 1, true).
|
AddItem(header.pages, 1, 1, true).
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -6,6 +6,7 @@ require (
|
|||||||
github.com/DataDog/zstd v1.4.5 // indirect
|
github.com/DataDog/zstd v1.4.5 // indirect
|
||||||
github.com/Sereal/Sereal v0.0.0-20200820125258-a016b7cda3f3 // indirect
|
github.com/Sereal/Sereal v0.0.0-20200820125258-a016b7cda3f3 // indirect
|
||||||
github.com/asdine/storm/v3 v3.2.1
|
github.com/asdine/storm/v3 v3.2.1
|
||||||
|
github.com/atotto/clipboard v0.1.4 // indirect
|
||||||
github.com/gdamore/tcell/v2 v2.1.0
|
github.com/gdamore/tcell/v2 v2.1.0
|
||||||
github.com/golang/protobuf v1.4.3 // indirect
|
github.com/golang/protobuf v1.4.3 // indirect
|
||||||
github.com/golang/snappy v0.0.2 // indirect
|
github.com/golang/snappy v0.0.2 // indirect
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -12,6 +12,8 @@ github.com/asdine/storm/v3 v3.2.1 h1:I5AqhkPK6nBZ/qJXySdI7ot5BlXSZ7qvDY1zAn5ZJac
|
|||||||
github.com/asdine/storm/v3 v3.2.1/go.mod h1:LEpXwGt4pIqrE/XcTvCnZHT5MgZCV6Ub9q7yQzOFWr0=
|
github.com/asdine/storm/v3 v3.2.1/go.mod h1:LEpXwGt4pIqrE/XcTvCnZHT5MgZCV6Ub9q7yQzOFWr0=
|
||||||
github.com/atotto/clipboard v0.1.2 h1:YZCtFu5Ie8qX2VmVTBnrqLSiU9XOWwqNRmdT3gIQzbY=
|
github.com/atotto/clipboard v0.1.2 h1:YZCtFu5Ie8qX2VmVTBnrqLSiU9XOWwqNRmdT3gIQzbY=
|
||||||
github.com/atotto/clipboard v0.1.2/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
github.com/atotto/clipboard v0.1.2/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||||
|
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||||
|
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
|||||||
Reference in New Issue
Block a user