-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathnote.tsx
129 lines (121 loc) · 4.07 KB
/
note.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { Accessor, Component, Match, Switch, createSignal, untrack } from "solid-js";
import NoteViewPlain from "./note/view_plain";
import NoteViewRendered from "./note/view_rendered";
import Icon from "./icon";
import { copyToClipboard } from "../core/helpers";
import { ToastType, useToast } from "../contexts/ToastProvider";
import { SetStoreFunction, Store } from "solid-js/store";
import Editor, { EditorState } from "./editor/editor";
import { Context } from "../../renderer/pkg/renderer";
const AUTO_SAVE_TIMEOUT = 2400;
export enum NoteMode {
RENDERED = "rendered",
PLAIN = "plain",
EDIT = "edit",
}
type NoteProps = {
mode: NoteMode,
setMode: (mode: NoteMode) => any,
content: Accessor<string>,
setContent: (content: string) => any,
context: Accessor<Context>,
isEditAllowed: boolean,
state: Store<EditorState>
setState: SetStoreFunction<EditorState>
onSave: (content: string) => any
}
const Note: Component<NoteProps> = (props) => {
const { pushToast } = useToast()
const [isFullscreen, setIsFullscreen] = createSignal(false);
const copyContentsToClipboard = async () => {
try {
await copyToClipboard(props.content() || "")
pushToast({ message: "copied to clipboard", type: ToastType.SUCCESS })
} catch (err) {
pushToast({ message: err.message, type: ToastType.ERROR })
}
}
const query_navigation_allowed = () => {
return (
!props.state.unsaved ||
props.state.unsaved && confirm("Note not saved, are you sure?")
)
}
return (
<div
class="flex flex-col gap-4 bg-base-100"
classList={{
"full-screen": isFullscreen(),
"p-4": isFullscreen(),
"min-h-screen": isFullscreen(),
}}
>
<div class="bg-base-200 shadow-md rounded-md flex justify-between">
<div class="tabs tabs-boxed">
<button
onclick={() => {
if (query_navigation_allowed()) {
props.setMode(NoteMode.RENDERED)
}
}}
class="tab"
classList={{ "tab-active": props.mode === NoteMode.RENDERED }}
title="switch to rendered view"
>Rendered</button>
<button
onclick={() => {
if (query_navigation_allowed()) {
props.setMode(NoteMode.PLAIN)
}
}}
class="tab"
classList={{ "tab-active": props.mode === NoteMode.PLAIN }}
title="switch to plain view"
>Plain</button>
<button
onclick={() => props.setMode(NoteMode.EDIT)}
class="tab"
disabled={!props.isEditAllowed}
classList={{ "tab-active": props.mode === NoteMode.EDIT }}
title="switch to editor"
>Editor</button>
</div>
<div class="join p-1">
<button
class="join-item btn btn-sm"
type="button"
title="Copy Note To Clipboard"
classList={{ "hidden": !window.isSecureContext }}
onClick={copyContentsToClipboard}
><Icon name="copy" />
</button>
<label class="join-item btn btn-sm swap">
<input
type="checkbox"
onchange={() => setIsFullscreen(!isFullscreen())}
checked={isFullscreen()}
/>
<div class="swap-on"><Icon name="minimize-2" size={18} /></div>
<div class="swap-off"><Icon name="maximize-2" size={18} /></div>
</label>
</div>
</div>
<Switch fallback={<NoteViewRendered content={props.content} context={props.context} />}>
<Match when={props.mode === NoteMode.PLAIN}>
<NoteViewPlain content={props.content} />
</Match>
<Match when={props.mode === NoteMode.EDIT}>
<Editor
content={untrack(props.content)}
autoSaveTimeout={AUTO_SAVE_TIMEOUT}
onSave={props.onSave}
state={props.state}
setState={props.setState}
isFullscreen={isFullscreen}
/>
</Match>
</Switch>
</div>
)
}
export default Note;