Skip to content

Commit f0051eb

Browse files
committed
feat: support long-click/press to edit a Todo
Clicking/tapping a description continues to act consistently with clicking the checkbox (toggles completion), but long-clicking/pressing will now open the edit dialog. Closes #33
1 parent d0638b2 commit f0051eb

File tree

9 files changed

+83
-17
lines changed

9 files changed

+83
-17
lines changed

dist/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"id": "todotxt",
33
"name": "TodoTxt",
4-
"version": "2.0.5",
4+
"version": "2.1.0",
55
"minAppVersion": "0.15.0",
66
"description": "Manage Todo.txt files.",
77
"author": "Mark Grimes",

dist/styles.css

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,12 @@
9595
}
9696

9797
#todotxt .todo {
98+
9899
border: 3px solid transparent;
99100
border-radius: 4px;
100-
}
101+
102+
display: flex;
103+
}
101104

102105
/* .todo:has(input:focus) { */
103106

dist/versions.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@
2424
"2.0.2": "0.15.0",
2525
"2.0.3": "0.15.0",
2626
"2.0.4": "0.15.0",
27-
"2.0.5": "0.15.0"
27+
"2.0.5": "0.15.0",
28+
"2.1.0": "0.15.0"
2829
}

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"id": "todotxt",
33
"name": "TodoTxt",
4-
"version": "2.0.5",
4+
"version": "2.1.0",
55
"minAppVersion": "0.15.0",
66
"description": "Manage Todo.txt files.",
77
"author": "Mark Grimes",

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "obsidian-sample-plugin",
3-
"version": "2.0.5",
3+
"version": "2.1.0",
44
"description": "This is a sample plugin for Obsidian (https://obsidian.md)",
55
"main": "dist/main.js",
66
"scripts": {

src/lib/useLongPress.tsx

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React, { useState, useRef, useCallback } from 'react';
2+
3+
type useLongPressType = (
4+
onLongPress: (event: any) => void,
5+
onClick: (event: any) => void,
6+
options?: {
7+
delay?: number;
8+
},
9+
) => {
10+
onMouseDown: (event: any) => void;
11+
onTouchStart: (event: any) => void;
12+
onMouseUp: (event: any) => void;
13+
onMouseLeave: (event: any) => void;
14+
onTouchEnd: (event: any) => void;
15+
};
16+
const useLongPress: useLongPressType = (
17+
onLongPress,
18+
onClick,
19+
{ delay = 500 } = {},
20+
) => {
21+
const [longPressTriggered, setLongPressTriggered] = useState(false);
22+
const timeout = useRef<any>();
23+
24+
const start = useCallback(
25+
(event: React.MouseEvent) => {
26+
timeout.current = setTimeout(() => {
27+
onLongPress(event);
28+
setLongPressTriggered(true);
29+
}, delay);
30+
},
31+
[onLongPress, delay],
32+
);
33+
34+
const clear = useCallback(
35+
(event: React.MouseEvent, shouldTriggerClick = true) => {
36+
timeout.current && clearTimeout(timeout.current);
37+
if (shouldTriggerClick && !longPressTriggered) {
38+
onClick(event);
39+
}
40+
setLongPressTriggered(false);
41+
},
42+
[onClick, longPressTriggered],
43+
);
44+
45+
return {
46+
onMouseDown: (e) => start(e),
47+
onTouchStart: (e) => start(e),
48+
onMouseUp: (e) => clear(e),
49+
onMouseLeave: (e) => clear(e, false),
50+
onTouchEnd: (e) => clear(e),
51+
};
52+
};
53+
54+
export default useLongPress;

src/styles.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@
8484
input[type="checkbox"] {
8585
margin-top: 0.125rem;
8686
}
87-
}
8887

89-
.todo {
9088
border: 3px solid transparent;
9189
border-radius: 4px;
90+
91+
display: flex;
9292
}
9393

9494
/* .todo:has(input:focus) { */

src/ui/todoview.tsx

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
TodoProject,
1212
TodoTag,
1313
} from '../lib/todo';
14+
import useLongPress from '../lib/useLongPress';
1415
import cn from '../lib/classNames';
1516

1617
type TodoViewProps = {
@@ -24,17 +25,23 @@ type TodoViewProps = {
2425
};
2526
export const TodoView = (props: TodoViewProps) => {
2627
const { todo } = props;
28+
const longPressProps = useLongPress(
29+
() => props.onEditClicked(todo),
30+
() => props.onCompleteToggle(todo),
31+
{ delay: 500 },
32+
);
2733

2834
return (
2935
<div className="todo">
30-
<label htmlFor={`todo-${todo.id}`} className="todo-label">
31-
<input
32-
type="checkbox"
33-
checked={todo.completed}
34-
id={`todo-${todo.id}`}
35-
onChange={() => props.onCompleteToggle(todo)}
36-
onKeyUp={(e) => props.onKeyPressed(e, todo)}
37-
/>
36+
<input
37+
type="checkbox"
38+
checked={todo.completed}
39+
id={`todo-${todo.id}`}
40+
onKeyUp={(e) => props.onKeyPressed(e, todo)}
41+
onChange={() => props.onCompleteToggle(todo)}
42+
/>
43+
{/* We can't use <label htmlFor={`todo-${todo.id}`}> here because it will cause the onCompleteToggle to fire twice */}
44+
<div className="todo-label" {...longPressProps}>
3845
<span
3946
className={cn(
4047
'todo-priority',
@@ -73,7 +80,7 @@ export const TodoView = (props: TodoViewProps) => {
7380
</button>
7481
</span>
7582
</span>
76-
</label>
83+
</div>
7784
</div>
7885
);
7986
};

versions.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@
2424
"2.0.2": "0.15.0",
2525
"2.0.3": "0.15.0",
2626
"2.0.4": "0.15.0",
27-
"2.0.5": "0.15.0"
27+
"2.0.5": "0.15.0",
28+
"2.1.0": "0.15.0"
2829
}

0 commit comments

Comments
 (0)