1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-14 10:16:26 +00:00

Compare commits

...

238 Commits

Author SHA1 Message Date
sota1235
87f9589be3 v0.8.1 2017-01-14 17:09:45 +09:00
Sota Sugiura
96413b9851 Merge pull request #218 from asmsuechan/feature-vim-keymap
Adds vim keymap setting
2017-01-14 17:03:20 +09:00
Sota Sugiura
9699ef6319 Merge pull request #237 from sota1235/feature-add_folder_on_note_detail
Add folder selector on note detail.
2017-01-14 16:57:00 +09:00
sota1235
dd8f4d60f0 fix: do not ignore dist file 2017-01-14 16:49:38 +09:00
asmsuechan
372f2e7319 Adds a prop keyMap to NoteDetail and SnippetNoteDetail 2017-01-14 16:39:50 +09:00
sota1235
1957d87dd7 modify: fix font size - folder name 2017-01-14 15:52:11 +09:00
sota1235
a148d17ba1 modify: add folder selector on top of note detail component 2017-01-14 15:44:28 +09:00
sota1235
297553c240 modify: move updated string to the bottom of note detail component 2017-01-14 14:54:08 +09:00
sota1235
f0fcaa6be7 modify: move zoom-pointer to left on note detail component 2017-01-14 14:47:06 +09:00
sota1235
cfa40f3ec1 refactor: remove unused component 2017-01-14 14:40:33 +09:00
sota1235
832c43de88 refactor: remove unused option 2017-01-14 14:36:26 +09:00
sota1235
1665e18edb fix: remove unused npm command 2017-01-14 13:52:10 +09:00
Sota Sugiura
fd1717046b Merge pull request #232 from BoostIO/simplified
I simplified.
2017-01-14 13:36:47 +09:00
sota1235
7fe7c555bc modify: add badge for TravisCI 2017-01-14 13:30:42 +09:00
Sota Sugiura
411a7a8e80 Merge pull request #233 from BoostIO/update-more-information
Update more information.
2017-01-14 13:27:38 +09:00
sota1235
196f5a7bf7 modify: add license section 2017-01-14 13:24:25 +09:00
Kazu Yokomizo
3fa326121a Update more information. 2017-01-12 20:35:53 +09:00
Kazu Yokomizo
cce69bea3a I simplified. 2017-01-12 20:29:20 +09:00
Sota Sugiura
f70cf7845d Merge pull request #231 from sota1235/master
[Refactor] Use ESLint instead of StandarJS and add settings for TravisCI
2017-01-12 00:48:05 +09:00
Sota Sugiura
bd0a326128 Merge pull request #20 from sota1235/feature-settings_for_travis
Settings for TravisCI
2017-01-12 00:34:44 +09:00
sota1235
897d99e043 modify: add badge of TravisCI on README 2017-01-12 00:28:10 +09:00
sota1235
b0f288e103 fix: ignore invalid tests 2017-01-12 00:23:44 +09:00
sota1235
7d26d46c7b modify: execute test on TravisCI 2017-01-12 00:01:12 +09:00
sota1235
5c7804fc40 modify: fix some codes pointed by eslint 2017-01-11 23:59:48 +09:00
sota1235
836f3af1ab add: files for using eslint 2017-01-11 23:52:22 +09:00
sota1235
67b89d4fe7 modfiy: install npm libraries for using eslint 2017-01-11 23:49:59 +09:00
sota1235
bc2d9d0fe2 modify: add settings for travisci 2017-01-11 23:38:43 +09:00
sota1235
79f33b9405 refactor: fix some coding style pointed by standard js 2017-01-11 23:35:02 +09:00
sota1235
ed9ddee5f1 refactor: fix by standardjs 2017-01-11 23:17:32 +09:00
sota1235
0d004b2f0a add: npm script for fix codes with standardjs 2017-01-11 23:13:50 +09:00
sota1235
f41ff77d76 add: npm command for checking coding style 2017-01-11 23:12:24 +09:00
sota1235
ae97a76d2e add: for using TravisCI 2017-01-11 23:10:09 +09:00
Sota Sugiura
3ca18c04c6 Merge pull request #221 from asmsuechan/remember-window-size
refs #207 Keeps window size
2017-01-11 23:03:01 +09:00
asmsuechan
2b03e6e956 refs #207 Fixes lengthy assignment 2017-01-11 22:56:12 +09:00
Sota Sugiura
010793a478 Merge pull request #228 from asmsuechan/iss-224
refs #224 Fixes the style of folder-list
2017-01-11 22:30:03 +09:00
asmsuechan
b136512ece refs #224 Fixes the style of folder-list 2017-01-11 10:21:53 +09:00
asmsuechan
9179c199fe refs #207 Keeps window size 2017-01-09 11:37:05 +09:00
Sota Sugiura
cfa4dfa817 Merge pull request #222 from asmsuechan/fix-npm-install
Fixes npm task bacause oh-my-cdn is removed
2017-01-09 11:35:13 +09:00
asmsuechan
6a73a3af97 Fixes npm task bacause oh-my-cdn is removed 2017-01-09 11:27:55 +09:00
Sota Sugiura
923c24fa6c Merge pull request #214 from asmsuechan/master
Fixes the theme of code block by codemirror
2017-01-08 23:53:10 +09:00
Sota Sugiura
4b1c8a3238 Merge pull request #206 from sota1235/hotfix-replace_old_url
Replace old url.
2017-01-08 23:46:54 +09:00
sota1235
76508fbc3b refactor: remove oh-my-cdn 2017-01-08 23:45:34 +09:00
sota1235
2bfda95ed8 modify: get flowchart.js from npm 2017-01-08 23:44:49 +09:00
Sota Sugiura
6e5082a470 Merge pull request #220 from BoostIO/Fixed-the-features-url(ja)
Fixed the features url(ja).
2017-01-08 19:47:32 +09:00
Kazu Yokomizo
a6cec44fc4 Fixed the features url(ja). 2017-01-08 19:45:45 +09:00
Sota Sugiura
600fab4f23 Merge pull request #219 from BoostIO/Fixed-the-features-url
Fixed the features url.
2017-01-08 19:45:26 +09:00
Kazu Yokomizo
12377b8caf Fixed the features url. 2017-01-08 19:44:46 +09:00
Sota Sugiura
250c6e488d Merge pull request #211 from BoostIO/Update-Author-&-Maintainer
Update Author & Maintainer
2017-01-08 19:42:35 +09:00
Kazu Yokomizo
3a9b57adae Merge branch 'master' into Update-Author-&-Maintainer 2017-01-08 19:41:31 +09:00
Sota Sugiura
74415956ac Merge pull request #213 from BoostIO/Updated-of-Japanese-readme
Updated of Japanese readme.
2017-01-08 19:36:08 +09:00
Sota Sugiura
33d7ed25a5 Merge pull request #212 from BoostIO/Fixed-link-and-typo
Fixed link and typo.
2017-01-08 19:33:05 +09:00
asmsuechan
df2de5c081 Adds note of caution next to keymap change select box 2017-01-08 18:16:32 +09:00
asmsuechan
7f4c58a84a Adds vim keymap setting 2017-01-08 17:52:52 +09:00
asmsuechan
7437b26e3c Fixes in order to handle default setting 2017-01-07 23:51:37 +09:00
asmsuechan
ee6d41859f Fixes the theme of code block by codemirror 2017-01-07 22:48:37 +09:00
Kazu Yokomizo
b368c3b5d8 Updated of Japanese readme.
Link, typo and list of Author & Maintainer
2017-01-07 19:33:31 +09:00
Kazu Yokomizo
b1ae2b0b6f Fixed link and typo. 2017-01-07 19:26:36 +09:00
Kazu Yokomizo
27a6d53c7f Update Author & Maintainer
add sota1235, Kohei TAKATA and Kazu Yokomizo.
2017-01-07 18:07:23 +09:00
sota1235
4caf3a81be fix: update the url of official homepage 2017-01-05 00:08:18 +09:00
sota1235
ab578f768f refactor: remove unused file 2017-01-05 00:06:03 +09:00
Sota Sugiura
e4212e796a Merge pull request #204 from sota1235/master
Use npm instead of using oh-my-cdn
2017-01-04 23:55:57 +09:00
Sota Sugiura
95b1ff9b41 Merge pull request #19 from sota1235/feature-remove_oh_my_cdn
Remove oh-my-cdn
2017-01-04 23:53:50 +09:00
sota1235
684d2c411e fix: path for react-dom.min.js 2017-01-04 23:51:29 +09:00
sota1235
42710cfee5 refactor: remove libraries in package.json 2017-01-04 23:46:06 +09:00
sota1235
277004fd9b refactor: replace with files in node_modules 2017-01-04 23:30:15 +09:00
sota1235
14f79c4c21 modify: install libraries with using npm, not using oh-my-cdn 2017-01-04 23:15:32 +09:00
Sota Sugiura
f88cd80dca Merge pull request #198 from sota1235/master
v0.8.0
2017-01-03 18:14:15 +09:00
sota1235
19ada1dbf6 v0.8.0 2017-01-03 18:13:12 +09:00
sota1235
7754ab1a2e modify: update readem for using new design 2017-01-03 18:11:47 +09:00
sota1235
de0a8837eb add: image file for readme 2017-01-03 18:09:15 +09:00
Sota Sugiura
042d059d53 Merge pull request #15 from sota1235/feature-design_renewal_rebase
Design renewal (v0.8.0)
2017-01-03 17:57:10 +09:00
sota1235
cba743c895 modify: fix sidenav style for folded mode 2017-01-03 17:56:30 +09:00
sota1235
24ee71ac06 modify: fix top for storage list 2017-01-03 17:51:00 +09:00
Sota Sugiura
0ec4ef3363 Merge pull request #18 from sota1235/hotfix-updated_string
Fix for updated string.
2017-01-03 17:33:31 +09:00
sota1235
98120a5e40 modify: fix style for updated date on note detail 2017-01-03 17:32:25 +09:00
Sota Sugiura
3cb2a6bf92 Merge pull request #17 from sota1235/hotfix-for_review
Some fix specified by @kazup.
2017-01-03 17:03:08 +09:00
sota1235
4b7262cb72 fix: text color on creating new folder form (dark theme) 2017-01-03 17:01:04 +09:00
sota1235
eac8b13d7b modify: fix padding for storage note count 2017-01-03 16:58:44 +09:00
sota1235
4458c58066 fix: scrolling for folder list 2017-01-03 16:56:52 +09:00
sota1235
245d603ae8 fix: Hello, 2017! 2017-01-03 16:54:07 +09:00
Sota Sugiura
e3d959522b Merge pull request #16 from sota1235/hotfix-border_for_hint_button
Fix style for hint button.
2017-01-03 16:30:58 +09:00
sota1235
124544452b fix: border-radius for hint button 2017-01-03 16:29:41 +09:00
sota1235
4534625084 modify: fix style for h1, h2 tag on markdown preview 2017-01-03 16:16:06 +09:00
sota1235
3e4342eec4 modify: remove underline for h tag on markdown previe 2017-01-03 16:16:06 +09:00
sota1235
0ed2d26129 fix: for renewal 2017-01-03 16:16:06 +09:00
sota1235
1b538993db modify: design for modal window creating new folder (dark theme) 2017-01-03 16:16:05 +09:00
sota1235
d67e4009e7 modify: change design for model window creating new folder 2017-01-03 16:16:05 +09:00
sota1235
7f066c4443 modify: fix some parameter for whole components 2017-01-03 16:16:05 +09:00
sota1235
2594ca984a modify: change style for snippet note on finder component 2017-01-03 16:16:05 +09:00
sota1235
0e089fadfb refactor: move component to common components directory 2017-01-03 16:16:05 +09:00
sota1235
e56518e13d modify: replace the component with common component 2017-01-03 16:16:05 +09:00
sota1235
c9bc0c89ff refactor: cut down the component from SideNav component 2017-01-03 16:16:05 +09:00
sota1235
b18b1171e7 refactor: replace storage item component with common component 2017-01-03 16:16:05 +09:00
sota1235
d65464401c refactor: replace component with common component 2017-01-03 16:16:05 +09:00
sota1235
e9a9e10c81 modify: cut down the component from SideNav component 2017-01-03 16:16:05 +09:00
sota1235
825cd6a93b modify: change design for note list on finder 2017-01-03 16:16:05 +09:00
sota1235
276471979a modify: move components file 2017-01-03 16:16:05 +09:00
sota1235
d6903edac7 modify: fix for black theme 2017-01-03 16:16:05 +09:00
sota1235
4e1b4bdd6a fix: border design for note item list 2017-01-03 16:16:05 +09:00
sota1235
52f0a5639d fix: markup for box-shadow 2017-01-03 16:16:05 +09:00
sota1235
58181d02b2 modify: change color for escape button on config modal 2017-01-03 16:16:05 +09:00
sota1235
1fea39f1b7 modify: add esc button for config modal 2017-01-03 16:16:05 +09:00
sota1235
ae97ff0f98 modify: fix some colors for config 2017-01-03 16:16:05 +09:00
sota1235
b2d7fa9e97 modify: fix style for button on storages config 2017-01-03 16:16:05 +09:00
sota1235
93e9235bb2 modify: markup style for info tab on config modal 2017-01-03 16:16:05 +09:00
sota1235
094bce20e2 modfiy: markup for UI config tab. 2017-01-03 16:16:05 +09:00
sota1235
2f9d4c447a modify: markup style for Hotkey config modal 2017-01-03 16:16:05 +09:00
sota1235
84eb790d93 modify: extend common config 2017-01-03 16:16:05 +09:00
sota1235
ebd07694db add: common style for config tabs 2017-01-03 16:16:05 +09:00
sota1235
2bbac8a6f4 modify: markup for storages config 2017-01-03 16:16:05 +09:00
sota1235
e74f5e835f modify: fix style for dark theme 2017-01-03 16:16:05 +09:00
sota1235
69e753cc71 modify: use new components insted of ConfigTab component 2017-01-03 16:16:05 +09:00
sota1235
b0978c772e modify: devide ConfigTab component for two components 2017-01-03 16:16:05 +09:00
sota1235
fb4dfbadf3 modify: change layout for config modal 2017-01-03 16:16:05 +09:00
sota1235
d19ff3ff17 modify: add shadow on notelist and topbar component(light theme) 2017-01-03 16:16:05 +09:00
sota1235
d0990be856 modify: fix font color for tags 2017-01-03 16:16:05 +09:00
sota1235
268d66b51d modify: add icon for NoteItem component 2017-01-03 16:16:05 +09:00
sota1235
c1df311e86 modify: add icon for NoteItemSimple component 2017-01-03 16:16:05 +09:00
sota1235
cc3bd41df2 modify: change text-align for title of the snipet files 2017-01-03 16:16:05 +09:00
sota1235
856979b455 modify: add border line on NoteList component 2017-01-03 16:16:05 +09:00
sota1235
47925489fd modify: not showing star when the note is not starred 2017-01-03 16:16:05 +09:00
sota1235
8aefb21123 modify: remove border color of slidebar 2017-01-03 16:16:05 +09:00
sota1235
e27751c18c modify: remove border-right of SideNav component 2017-01-03 16:16:05 +09:00
sota1235
a3f3fdcc71 modify: change base color for dark theme 2017-01-03 16:16:04 +09:00
sota1235
a757576920 fix: get js-sequence-diagrams from npm, not CDN 2017-01-03 16:16:04 +09:00
sota1235
c4eb28d241 modify: change style for NoteItemSimple component 2017-01-03 16:15:45 +09:00
sota1235
aba6c2eb4f add: style sheet for NoteItemSimple component 2017-01-03 16:15:45 +09:00
sota1235
ecb91b3155 refactor: remove unused styles 2017-01-03 16:15:45 +09:00
sota1235
7374b1cc70 refactor: replace code with micro components 2017-01-03 16:15:45 +09:00
sota1235
e8f2972659 modify: remove duplicated codes 2017-01-03 16:15:45 +09:00
sota1235
5bef19a306 add: stylesheet for note-item components 2017-01-03 16:15:45 +09:00
sota1235
54d9e02a42 add: NoteItem component on NoteList component when using simple display mode 2017-01-03 16:15:45 +09:00
sota1235
4f479a8baf add: NoteItem component on NoteList component 2017-01-03 16:15:45 +09:00
sota1235
e7e6194cac modify: not showing the star on the note-list component when using the simple mode 2017-01-03 16:15:45 +09:00
sota1235
113abbb94d refactor: remove unused component 2017-01-03 16:15:45 +09:00
sota1235
d9d0651352 modify: adjust space on note-detail component 2017-01-03 16:15:45 +09:00
sota1235
e27af9f6c1 fix: style for the TagSelect component 2017-01-03 16:15:45 +09:00
sota1235
11d820356d modify: change style for note-detail component (snipet mode) 2017-01-03 16:15:45 +09:00
sota1235
0945aab232 modify: fix text color on note list(dark theme) 2017-01-03 16:15:45 +09:00
sota1235
e4744221ee modify: fix the style of the tooltip for creating new note 2017-01-03 16:15:45 +09:00
sota1235
5f71b24f8d modify: change background-color for note-detail component 2017-01-03 16:15:45 +09:00
sota1235
095a29972a modify: fix text on the modal window for creating new note 2017-01-03 16:15:45 +09:00
sota1235
76bdb708fa refactor: move the code for note info to NoteDetailInfo.styl 2017-01-03 16:15:45 +09:00
sota1235
7c3c08fd96 modify: add color variable for note-detail component 2017-01-03 16:15:45 +09:00
sota1235
a4a2e09429 modify: remove tooltips 2017-01-03 16:15:45 +09:00
sota1235
4ed0ae5e2d modify: change icon for controling viewing mode of note list 2017-01-03 16:15:45 +09:00
sota1235
4cb5e43357 modify: change icon for All Notes 2017-01-03 16:15:45 +09:00
sota1235
b0fecc6b51 modify: fix style for dark theme 2017-01-03 16:15:45 +09:00
sota1235
dd4236ca89 modify: add Star on note right side 2017-01-03 16:15:45 +09:00
sota1235
5da908c759 modfiy: change style for note list 2017-01-03 16:15:45 +09:00
sota1235
fcce1d406d modify: move variables to global file 2017-01-03 16:15:45 +09:00
sota1235
5a01f39dc7 modfiy: fix style for sort button 2017-01-03 16:15:45 +09:00
sota1235
ea1d76f853 modfiy: change style for top bar 2017-01-03 16:15:45 +09:00
sota1235
2356d8a64f modify: add color variable for style 2017-01-03 16:15:45 +09:00
sota1235
969f82b903 modify: remove bordertop of note list 2017-01-03 16:15:45 +09:00
sota1235
fb90907abf modify: change ui-backgroundColor 2017-01-03 16:15:45 +09:00
sota1235
cbd4cd940c modify: fix padding-left on side nav bar 2017-01-03 16:15:45 +09:00
sota1235
6b18c6182e modify: fix style for storage item 2017-01-03 16:15:45 +09:00
sota1235
09164aa0c9 modify: fix space on side nav 2017-01-03 16:15:45 +09:00
sota1235
b83dadddb7 modify: remove border-bottom of menu button 2017-01-03 16:15:45 +09:00
sota1235
b3263b41ff Revert "fix: default.css not found"
This reverts commit 7b55454a73b3eebbfe1ed4684157c2d822ee2f05.
2017-01-03 16:15:45 +09:00
sota1235
1118149b9e modify: remove add tag button 2017-01-03 16:15:45 +09:00
sota1235
b6fc24c6e7 modify: fix style for more option button 2017-01-03 16:15:45 +09:00
sota1235
441edf4667 add: show last updated date on detail top bar 2017-01-03 16:15:45 +09:00
sota1235
74068eaa3d modify: fix test and logic 2017-01-03 16:15:45 +09:00
sota1235
c11bd9e7eb fix: default.css not found 2017-01-03 16:15:45 +09:00
sota1235
b21a82ea6b modify: add date string for detail 2017-01-03 16:15:45 +09:00
sota1235
cf455a13d5 add: util method for generating date 2017-01-03 16:15:45 +09:00
sota1235
c492f3529e modify: remove tooltip of 'more option' button 2017-01-03 16:15:45 +09:00
sota1235
40d7ba4bcc modify: remove border from options button 2017-01-03 16:15:45 +09:00
sota1235
686bc49230 modify: change color for adding tag button 2017-01-03 16:15:45 +09:00
sota1235
6550af698a modify: add button for tag component 2017-01-03 16:15:45 +09:00
sota1235
aac5cbf53e modify: fix active color for favorite star button 2017-01-03 16:15:45 +09:00
sota1235
00636db87c modify: remove animatino for removing tag button 2017-01-03 16:15:45 +09:00
sota1235
6231b8ad57 modify: fix size of removet tag button 2017-01-03 16:15:45 +09:00
sota1235
f2a41aa049 modify: change design for star button 2017-01-03 16:15:45 +09:00
sota1235
bb87b80a92 modify: add variable for star button's color 2017-01-03 16:15:45 +09:00
sota1235
ebfbe29217 modify: change design for tag 2017-01-03 16:15:45 +09:00
sota1235
fad837e148 modify: remove tag icon 2017-01-03 16:15:45 +09:00
sota1235
7dc84c0d6d revert: add FolderSelect Component again 2017-01-03 16:15:45 +09:00
sota1235
74807fe251 Revert "remove: unused file"
This reverts commit db1d0fb5d57967e586bd3e2cb02268f69a718861.
2017-01-03 16:15:45 +09:00
sota1235
bf9773be20 modify: move star on left side 2017-01-03 16:15:45 +09:00
sota1235
18961ff555 refactor: remove context button on top bar 2017-01-03 16:15:45 +09:00
sota1235
1f6e0342d6 modify: fix min width of window 2017-01-03 16:15:45 +09:00
sota1235
7d2bc58ba2 modify: change height of menu on SideNav component 2017-01-03 16:15:45 +09:00
sota1235
556b53181f modify: fix to use navWidth instead of listWidth 2017-01-03 16:15:45 +09:00
sota1235
ca904d69e5 modify: add comment for handleMousUp action 2017-01-03 16:15:45 +09:00
sota1235
f461d459d2 modify: change width of SideNav component 2017-01-03 16:15:45 +09:00
sota1235
6e535c11fd refactor: separate styl file 2017-01-03 16:15:45 +09:00
sota1235
49d3262380 remove: unused file 2017-01-03 16:15:45 +09:00
sota1235
1ee3dec0cc modify: fix style for detail info 2017-01-03 16:15:44 +09:00
sota1235
15637642bb refactor: remove FolderSelect Component 2017-01-03 16:15:44 +09:00
sota1235
3c950c2b9e refactor: remove ShareButton 2017-01-03 16:15:44 +09:00
Sota Sugiura
7811039651 Merge pull request #196 from asmsuechan/master
URL is no longer available
2016-12-31 00:39:16 +09:00
asmsuechan
ec5f7b38d0 Updates invalid url of sequence-diagram 2016-12-30 23:14:25 +09:00
sota1235
2bb361dc19 v0.7.5 2016-12-20 17:41:42 +09:00
Sota Sugiura
3445e484ae Merge pull request #188 from less-easy-way/patch-1
Just fix a trivial typo.
2016-12-14 02:43:39 +09:00
Jae-woo Kim
efd6bf2afe Just fix a trivial typo.
Just fixed a trivial typo.
어쩌다 발견하게 됐네요. :)
2016-12-13 23:28:50 +09:00
sota1235
cd2e6e1b24 v0.7.4 2016-12-13 20:33:04 +09:00
sota1235
99b8d24db3 hotfix: add dependent libraries 2016-12-13 20:24:13 +09:00
sota1235
8116b569c1 v0.7.3 2016-12-13 13:48:03 +09:00
sota1235
da791c5fed fix: link for boostnote store 2016-12-13 13:36:56 +09:00
sota1235
fbd9c59bfd modify: add contributor 2016-12-13 12:55:25 +09:00
Junyoung Choi
3a1b3d19c5 Merge pull request #166 from bkjohnson/master
Adding menu back in temporarily to fix shortcuts.
2016-10-28 12:15:03 +09:00
Brooks Johnson
238076f534 Adding menu back in temporarily to fix shortcuts. 2016-10-27 20:48:01 -05:00
Junyoung Choi
214d74ae11 Merge pull request #164 from bkjohnson/master
Minor accelerator updates
2016-10-27 21:05:01 +09:00
Brooks Johnson
30324f6113 Refactors color changes into mixin 2016-10-26 23:43:01 -05:00
Brooks Johnson
68f0a25873 Adds dark theme to controls in config window. 2016-10-26 20:39:54 -05:00
Brooks Johnson
cd5bc4e930 Simplify OSX accelerators (see here: http://electron.atom.io/docs/api/accelerator/#platform-notice) 2016-10-26 19:51:35 -05:00
Brooks Johnson
1d8f729c95 Update accelerators to use var instead of function 2016-10-26 19:37:44 -05:00
Dick Choi
f0d2fb53d4 add sequence diagram 2016-10-26 13:06:02 +09:00
Dick Choi
0445c680ba debounce rendering 2016-10-26 10:48:04 +09:00
Dick Choi
12453942c8 use _.forEach instead of Array.prototype.forEach.call 2016-10-26 10:47:51 +09:00
Dick Choi
b18a5be940 flowchart 2016-10-26 10:03:20 +09:00
Junyoung Choi
c2234747e8 Merge pull request #161 from twhiting/master
Updated readme english & reformatting
2016-10-25 09:49:18 +09:00
Trent
d6c9ab43ec Fixed spacing issue with markdown syntax 2016-10-24 17:29:09 -06:00
twhiting
db16a87f74 Formatting fixes for readme 2016-10-24 16:55:21 -06:00
twhiting
5b0d2ec97b Updated readme with english fixes + reformatting 2016-10-24 16:52:04 -06:00
Dick Choi
b906db3b24 fix syntax name bug of snippet note 2016-10-24 18:48:04 +09:00
Dick Choi
df0af2a11f Render codefence by codemirror rather than by hljs 2016-10-24 18:05:01 +09:00
Junyoung Choi
706dd3e616 Merge pull request #160 from tejado/master
Fix of storage unlink in preference popup
2016-10-22 16:50:47 +09:00
Dick Choi
bbec58e049 update contributors
add Mike Resoli and tjado
2016-10-21 16:59:37 +09:00
Dick Choi
381b7d85f4 keep the convention 2016-10-21 08:43:00 +09:00
Junyoung Choi
c17c056af3 Merge pull request #157 from tejado/master
Fix syntax error (unexpected token)
2016-10-21 08:13:18 +09:00
Junyoung Choi
a26a85cd1f Merge pull request #159 from mikeres0/patch-1
Improved error messaging
2016-10-21 02:50:48 +09:00
Mike Resoli
9b68b1d327 Improved error messaging
Instead of a standard `console.log` I've added an alert. Pressing the button and getting nowhere is not good from a user perspective.
2016-10-20 16:50:47 +01:00
tjado
6a6631052e Fix of storage unlink in preference popup 2016-10-20 13:35:02 +02:00
tjado
d4ad3a953a Fix syntax error (unexpected token) 2016-10-20 12:56:07 +02:00
Junyoung Choi
7bb63a78c5 Merge pull request #150 from mikeres0/master
Various updates
2016-10-20 00:53:30 +09:00
Mike Resoli
26c859f14c added npm run vendor to build.md 2016-10-19 14:41:01 +01:00
Mike Resoli
dd5c9bf3f6 Spelling mistake in index.js 2016-10-19 11:17:35 +01:00
Dick Choi
3db40fea31 v0.7.2 2016-10-18 14:46:17 +09:00
Dick Choi
8f1c198406 hot fix: Wrong behavior with Japanese IME keyboard 2016-10-18 13:42:10 +09:00
Dick Choi
ac65a3c86e v0.7.1 2016-10-18 00:32:28 +09:00
Dick Choi
79abcd90f6 fix tooltip layout of SideNav 2016-10-18 00:08:52 +09:00
Dick Choi
d614abdec6 fix wrong border color 2016-10-18 00:07:22 +09:00
Mike Resoli
44d754c59d Hid menu 2016-10-17 13:40:13 +01:00
Dick Choi
247d1db5d5 fix IME popup bug 2016-10-17 18:58:28 +09:00
121 changed files with 2073 additions and 2039 deletions

3
.eslintignore Normal file
View File

@@ -0,0 +1,3 @@
node_modules/
compiled/
dist/

6
.eslintrc Normal file
View File

@@ -0,0 +1,6 @@
{
"extends": ["standard", "standard-jsx"],
"rules": {
"no-useless-escape": 0
}
}

6
.travis.yml Normal file
View File

@@ -0,0 +1,6 @@
language: node_js
node_js:
- 'stable'
- 'lts/*'
script: npm run lint && npm run test

View File

@@ -37,6 +37,9 @@ export default class CodeEditor extends React.Component {
} }
this.props.onBlur != null && this.props.onBlur(e) this.props.onBlur != null && this.props.onBlur(e)
} }
this.loadStyleHandler = (e) => {
this.editor.refresh()
}
} }
componentDidMount () { componentDidMount () {
@@ -49,7 +52,8 @@ export default class CodeEditor extends React.Component {
indentUnit: this.props.indentSize, indentUnit: this.props.indentSize,
tabSize: this.props.indentSize, tabSize: this.props.indentSize,
indentWithTabs: this.props.indentType !== 'space', indentWithTabs: this.props.indentType !== 'space',
keyMap: 'sublime', keyMap: this.props.keyMap,
inputStyle: 'textarea',
extraKeys: { extraKeys: {
Tab: function (cm) { Tab: function (cm) {
if (cm.somethingSelected()) cm.indentSelection('add') if (cm.somethingSelected()) cm.indentSelection('add')
@@ -71,11 +75,16 @@ export default class CodeEditor extends React.Component {
this.editor.on('blur', this.blurHandler) this.editor.on('blur', this.blurHandler)
this.editor.on('change', this.changeHandler) this.editor.on('change', this.changeHandler)
let editorTheme = document.getElementById('editorTheme')
editorTheme.addEventListener('load', this.loadStyleHandler)
} }
componentWillUnmount () { componentWillUnmount () {
this.editor.off('blur', this.blurHandler) this.editor.off('blur', this.blurHandler)
this.editor.off('change', this.changeHandler) this.editor.off('change', this.changeHandler)
let editorTheme = document.getElementById('editorTheme')
editorTheme.removeEventListener('load', this.loadStyleHandler)
} }
componentDidUpdate (prevProps, prevState) { componentDidUpdate (prevProps, prevState) {
@@ -85,7 +94,7 @@ export default class CodeEditor extends React.Component {
} }
if (prevProps.theme !== this.props.theme) { if (prevProps.theme !== this.props.theme) {
this.editor.setOption('theme', this.props.theme) this.editor.setOption('theme', this.props.theme)
needRefresh = true // editor should be refreshed after css loaded
} }
if (prevProps.fontSize !== this.props.fontSize) { if (prevProps.fontSize !== this.props.fontSize) {
needRefresh = true needRefresh = true
@@ -93,6 +102,9 @@ export default class CodeEditor extends React.Component {
if (prevProps.fontFamily !== this.props.fontFamily) { if (prevProps.fontFamily !== this.props.fontFamily) {
needRefresh = true needRefresh = true
} }
if (prevProps.keyMap !== this.props.keyMap) {
needRefresh = true
}
if (prevProps.indentSize !== this.props.indentSize) { if (prevProps.indentSize !== this.props.indentSize) {
this.editor.setOption('indentUnit', this.props.indentSize) this.editor.setOption('indentUnit', this.props.indentSize)
@@ -185,6 +197,7 @@ CodeEditor.propTypes = {
CodeEditor.defaultProps = { CodeEditor.defaultProps = {
readOnly: false, readOnly: false,
theme: 'xcode', theme: 'xcode',
keyMap: 'sublime',
fontSize: 14, fontSize: 14,
fontFamily: 'Monaco, Consolas', fontFamily: 'Monaco, Consolas',
indentSize: 4, indentSize: 4,

View File

@@ -9,7 +9,8 @@ class MarkdownEditor extends React.Component {
super(props) super(props)
this.state = { this.state = {
status: 'PREVIEW' status: 'PREVIEW',
renderValue: props.value
} }
} }
@@ -21,6 +22,33 @@ class MarkdownEditor extends React.Component {
this.value = this.refs.code.value this.value = this.refs.code.value
} }
componentWillReceiveProps (props) {
if (props.value !== this.props.value) {
this.queueRendering(props.value)
}
}
componentWillUnmount () {
this.cancelQueue()
}
queueRendering (value) {
clearTimeout(this.renderTimer)
this.renderTimer = setTimeout(() => {
this.renderPreview(value)
}, 500)
}
cancelQueue () {
clearTimeout(this.renderTimer)
}
renderPreview (value) {
this.setState({
renderValue: value
})
}
handleChange (e) { handleChange (e) {
this.value = this.refs.code.value this.value = this.refs.code.value
this.props.onChange(e) this.props.onChange(e)
@@ -110,10 +138,13 @@ class MarkdownEditor extends React.Component {
reload () { reload () {
this.refs.code.reload() this.refs.code.reload()
this.cancelQueue()
this.renderPreview(this.props.value)
} }
render () { render () {
let { className, value, config } = this.props let { className, value, config } = this.props
let editorFontSize = parseInt(config.editor.fontSize, 10) let editorFontSize = parseInt(config.editor.fontSize, 10)
if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14 if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14
let editorIndentSize = parseInt(config.editor.indentSize, 10) let editorIndentSize = parseInt(config.editor.indentSize, 10)
@@ -135,6 +166,7 @@ class MarkdownEditor extends React.Component {
mode='GitHub Flavored Markdown' mode='GitHub Flavored Markdown'
value={value} value={value}
theme={config.editor.theme} theme={config.editor.theme}
keyMap={config.editor.keyMap}
fontFamily={config.editor.fontFamily} fontFamily={config.editor.fontFamily}
fontSize={editorFontSize} fontSize={editorFontSize}
indentType={config.editor.indentType} indentType={config.editor.indentType}
@@ -148,15 +180,17 @@ class MarkdownEditor extends React.Component {
} }
style={previewStyle} style={previewStyle}
theme={config.ui.theme} theme={config.ui.theme}
keyMap={config.editor.keyMap}
fontSize={config.preview.fontSize} fontSize={config.preview.fontSize}
fontFamily={config.preview.fontFamily} fontFamily={config.preview.fontFamily}
codeBlockTheme={config.preview.codeBlockTheme} codeBlockTheme={config.preview.codeBlockTheme}
codeBlockFontFamily={config.editor.fontFamily} codeBlockFontFamily={config.editor.fontFamily}
lineNumber={config.preview.lineNumber} lineNumber={config.preview.lineNumber}
indentSize={editorIndentSize}
ref='preview' ref='preview'
onContextMenu={(e) => this.handleContextMenu(e)} onContextMenu={(e) => this.handleContextMenu(e)}
tabIndex='0' tabIndex='0'
value={value} value={this.state.renderValue}
onMouseUp={(e) => this.handlePreviewMouseUp(e)} onMouseUp={(e) => this.handlePreviewMouseUp(e)}
onMouseDown={(e) => this.handlePreviewMouseDown(e)} onMouseDown={(e) => this.handlePreviewMouseDown(e)}
onCheckboxClick={(e) => this.handleCheckboxClick(e)} onCheckboxClick={(e) => this.handleCheckboxClick(e)}

View File

@@ -1,11 +1,77 @@
import React, { PropTypes } from 'react' import React, { PropTypes } from 'react'
import markdown from 'browser/lib/markdown' import markdown from 'browser/lib/markdown'
import _ from 'lodash' import _ from 'lodash'
import hljsTheme from 'browser/lib/hljsThemes' import CodeMirror from 'codemirror'
import consts from 'browser/lib/consts'
import Raphael from 'raphael'
import flowchart from 'flowchart'
import SequenceDiagram from 'js-sequence-diagrams'
function decodeHTMLEntities (text) {
var entities = [
['apos', '\''],
['amp', '&'],
['lt', '<'],
['gt', '>']
]
for (var i = 0, max = entities.length; i < max; ++i) {
text = text.replace(new RegExp('&' + entities[i][0] + ';', 'g'), entities[i][1])
}
return text
}
const { remote } = require('electron')
const { app } = remote
const path = require('path')
const markdownStyle = require('!!css!stylus?sourceMap!./markdown.styl')[0][1] const markdownStyle = require('!!css!stylus?sourceMap!./markdown.styl')[0][1]
const { shell } = require('electron') const appPath = 'file://' + (process.env.NODE_ENV === 'production'
? app.getAppPath()
: path.resolve())
function buildStyle (fontFamily, fontSize, codeBlockFontFamily, lineNumber) {
return `
@font-face {
font-family: 'Lato';
src: url('${appPath}/resources/fonts/Lato-Regular.woff2') format('woff2'), /* Modern Browsers */
url('${appPath}/resources/fonts/Lato-Regular.woff') format('woff'), /* Modern Browsers */
url('${appPath}/resources/fonts/Lato-Regular.ttf') format('truetype');
font-style: normal;
font-weight: normal;
text-rendering: optimizeLegibility;
}
${markdownStyle}
body {
font-family: ${fontFamily.join(', ')};
font-size: ${fontSize}px;
}
code {
font-family: ${codeBlockFontFamily.join(', ')};
}
.lineNumber {
${lineNumber && 'display: block !important;'}
font-family: ${codeBlockFontFamily.join(', ')};
}
h1, h2 {
border: none;
}
h1 {
padding-bottom: 4px;
margin: 1em 0 8px;
}
h2 {
padding-bottom: 0.2em;
margin: 1em 0 0.37em;
}
`
}
const { shell } = require('electron')
const OSX = global.process.platform === 'darwin' const OSX = global.process.platform === 'darwin'
const defaultFontFamily = ['helvetica', 'arial', 'sans-serif'] const defaultFontFamily = ['helvetica', 'arial', 'sans-serif']
@@ -30,14 +96,15 @@ export default class MarkdownPreview extends React.Component {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
let href = e.target.getAttribute('href') let anchor = e.target.closest('a')
let href = anchor.getAttribute('href')
if (_.isString(href) && href.match(/^#/)) { if (_.isString(href) && href.match(/^#/)) {
let targetElement = this.refs.root.contentWindow.document.getElementById(href.substring(1, href.length)) let targetElement = this.refs.root.contentWindow.document.getElementById(href.substring(1, href.length))
if (targetElement != null) { if (targetElement != null) {
this.getWindow().scrollTo(0, targetElement.offsetTop) this.getWindow().scrollTo(0, targetElement.offsetTop)
} }
} else { } else {
shell.openExternal(e.target.href) shell.openExternal(href)
} }
} }
@@ -68,9 +135,17 @@ export default class MarkdownPreview extends React.Component {
} }
componentDidMount () { componentDidMount () {
this.refs.root.setAttribute('sandbox', 'allow-same-origin') this.refs.root.setAttribute('sandbox', 'allow-scripts')
this.refs.root.contentWindow.document.body.addEventListener('contextmenu', this.contextMenuHandler) this.refs.root.contentWindow.document.body.addEventListener('contextmenu', this.contextMenuHandler)
this.refs.root.contentWindow.document.head.innerHTML = `
<style id='style'></style>
<link rel="stylesheet" href="${appPath}/node_modules/katex/dist/katex.min.css">
<link rel="stylesheet" href="${appPath}/node_modules/codemirror/lib/codemirror.css">
<link rel="stylesheet" id="codeTheme">
`
this.rewriteIframe() this.rewriteIframe()
this.applyStyle()
this.refs.root.contentWindow.document.addEventListener('mousedown', this.mouseDownHandler) this.refs.root.contentWindow.document.addEventListener('mousedown', this.mouseDownHandler)
this.refs.root.contentWindow.document.addEventListener('mouseup', this.mouseUpHandler) this.refs.root.contentWindow.document.addEventListener('mouseup', this.mouseUpHandler)
@@ -83,71 +158,113 @@ export default class MarkdownPreview extends React.Component {
} }
componentDidUpdate (prevProps) { componentDidUpdate (prevProps) {
if (prevProps.value !== this.props.value || if (prevProps.value !== this.props.value) this.rewriteIframe()
prevProps.fontFamily !== this.props.fontFamily || if (prevProps.fontFamily !== this.props.fontFamily ||
prevProps.fontSize !== this.props.fontSize || prevProps.fontSize !== this.props.fontSize ||
prevProps.codeBlockFontFamily !== this.props.codeBlockFontFamily || prevProps.codeBlockFontFamily !== this.props.codeBlockFontFamily ||
prevProps.codeBlockTheme !== this.props.codeBlockTheme || prevProps.codeBlockTheme !== this.props.codeBlockTheme ||
prevProps.lineNumber !== this.props.lineNumber || prevProps.lineNumber !== this.props.lineNumber ||
prevProps.theme !== this.props.theme prevProps.theme !== this.props.theme) {
) this.rewriteIframe() this.applyStyle()
this.rewriteIframe()
}
} }
rewriteIframe () { applyStyle () {
Array.prototype.forEach.call(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => { let { fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme } = this.props
el.removeEventListener('click', this.anchorClickHandler)
})
Array.prototype.forEach.call(this.refs.root.contentWindow.document.querySelectorAll('input[type="checkbox"]'), (el) => {
el.removeEventListener('click', this.checkboxClickHandler)
})
let { value, fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme, theme } = this.props
fontFamily = _.isString(fontFamily) && fontFamily.trim().length > 0 fontFamily = _.isString(fontFamily) && fontFamily.trim().length > 0
? [fontFamily].concat(defaultFontFamily) ? [fontFamily].concat(defaultFontFamily)
: defaultFontFamily : defaultFontFamily
codeBlockFontFamily = _.isString(codeBlockFontFamily) && codeBlockFontFamily.trim().length > 0 codeBlockFontFamily = _.isString(codeBlockFontFamily) && codeBlockFontFamily.trim().length > 0
? [codeBlockFontFamily].concat(defaultCodeBlockFontFamily) ? [codeBlockFontFamily].concat(defaultCodeBlockFontFamily)
: defaultCodeBlockFontFamily : defaultCodeBlockFontFamily
codeBlockTheme = hljsTheme().some((theme) => theme.name === codeBlockTheme) ? codeBlockTheme : 'xcode'
this.refs.root.contentWindow.document.head.innerHTML = ` this.setCodeTheme(codeBlockTheme)
<style> this.getWindow().document.getElementById('style').innerHTML = buildStyle(fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme, lineNumber)
@font-face { }
font-family: 'Lato';
src: url('../resources/fonts/Lato-Regular.woff2') format('woff2'), /* Modern Browsers */ setCodeTheme (theme) {
url('../resources/fonts/Lato-Regular.woff') format('woff'), /* Modern Browsers */ theme = consts.THEMES.some((_theme) => _theme === theme) && theme !== 'default'
url('../resources/fonts/Lato-Regular.ttf') format('truetype'); ? theme
font-style: normal; : 'elegant'
font-weight: normal; this.getWindow().document.getElementById('codeTheme').href = `${appPath}/node_modules/codemirror/theme/${theme}.css`
text-rendering: optimizeLegibility; }
}
${markdownStyle} rewriteIframe () {
body { _.forEach(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
font-family: ${fontFamily.join(', ')}; el.removeEventListener('click', this.anchorClickHandler)
font-size: ${fontSize}px; })
} _.forEach(this.refs.root.contentWindow.document.querySelectorAll('input[type="checkbox"]'), (el) => {
code { el.removeEventListener('click', this.checkboxClickHandler)
font-family: ${codeBlockFontFamily.join(', ')}; })
}
.lineNumber { let { value, theme, indentSize, codeBlockTheme } = this.props
${lineNumber && 'display: block !important;'}
font-family: ${codeBlockFontFamily.join(', ')};
opacity: 0.5;
}
</style>
<link rel="stylesheet" href="../node_modules/highlight.js/styles/${codeBlockTheme}.css">
<link rel="stylesheet" href="../compiled/katex-style.css">
`
this.refs.root.contentWindow.document.body.setAttribute('data-theme', theme) this.refs.root.contentWindow.document.body.setAttribute('data-theme', theme)
this.refs.root.contentWindow.document.body.innerHTML = markdown.render(value) this.refs.root.contentWindow.document.body.innerHTML = markdown.render(value)
Array.prototype.forEach.call(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => { _.forEach(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
el.addEventListener('click', this.anchorClickHandler) el.addEventListener('click', this.anchorClickHandler)
}) })
Array.prototype.forEach.call(this.refs.root.contentWindow.document.querySelectorAll('input[type="checkbox"]'), (el) => {
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('input[type="checkbox"]'), (el) => {
el.addEventListener('click', this.checkboxClickHandler) el.addEventListener('click', this.checkboxClickHandler)
}) })
codeBlockTheme = consts.THEMES.some((_theme) => _theme === codeBlockTheme)
? codeBlockTheme
: 'default'
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('.code code'), (el) => {
let syntax = CodeMirror.findModeByName(el.className)
if (syntax == null) syntax = CodeMirror.findModeByName('Plain Text')
CodeMirror.requireMode(syntax.mode, () => {
let content = el.innerHTML
el.innerHTML = ''
el.parentNode.className += ` cm-s-${codeBlockTheme} CodeMirror`
CodeMirror.runMode(content, syntax.mime, el, {
tabSize: indentSize
})
})
})
let opts = {}
// if (this.props.theme === 'dark') {
// opts['font-color'] = '#DDD'
// opts['line-color'] = '#DDD'
// opts['element-color'] = '#DDD'
// opts['fill'] = '#3A404C'
// }
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('.flowchart'), (el) => {
Raphael.setWindow(this.getWindow())
try {
let diagram = flowchart.parse(decodeHTMLEntities(el.innerHTML))
el.innerHTML = ''
diagram.drawSVG(el, opts)
_.forEach(el.querySelectorAll('a'), (el) => {
el.addEventListener('click', this.anchorClickHandler)
})
} catch (e) {
console.error(e)
el.className = 'flowchart-error'
el.innerHTML = 'Flowchart parse error: ' + e.message
}
})
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('.sequence'), (el) => {
Raphael.setWindow(this.getWindow())
try {
let diagram = SequenceDiagram.parse(decodeHTMLEntities(el.innerHTML))
el.innerHTML = ''
diagram.drawSVG(el, {theme: 'simple'})
_.forEach(el.querySelectorAll('a'), (el) => {
el.addEventListener('click', this.anchorClickHandler)
})
} catch (e) {
console.error(e)
el.className = 'sequence-error'
el.innerHTML = 'Sequence diagram parse error: ' + e.message
}
})
} }
focus () { focus () {

View File

@@ -0,0 +1,100 @@
/**
* @fileoverview Note item component.
*/
import React, { PropTypes } from 'react'
import { isArray } from 'lodash'
import CSSModules from 'browser/lib/CSSModules'
import styles from './NoteItem.styl'
/**
* @description Tag element component.
* @param {string} tagName
* @return {React.Component}
*/
const TagElement = ({ tagName }) => (
<span styleName='item-bottom-tagList-item' key={tagName}>
{tagName}
</span>
)
/**
* @description Tag element list component.
* @param {Array|null} tags
* @return {React.Component}
*/
const TagElementList = (tags) => {
if (!isArray(tags)) {
return []
}
const tagElements = tags.map(tag => (
TagElement({tagName: tag})
))
return tagElements
}
/**
* @description Note item component when using normal display mode.
* @param {boolean} isActive
* @param {Object} note
* @param {Function} handleNoteClick
* @param {Function} handleNoteContextMenu
* @param {string} dateDisplay
*/
const NoteItem = ({ isActive, note, dateDisplay, handleNoteClick, handleNoteContextMenu }) => (
<div styleName={isActive
? 'item--active'
: 'item'
}
key={`${note.storage}-${note.key}`}
onClick={e => handleNoteClick(e, `${note.storage}-${note.key}`)}
onContextMenu={e => handleNoteContextMenu(e, `${note.storage}-${note.key}`)}
>
<div styleName='item-wrapper'>
<div styleName='item-bottom-time'>{dateDisplay}</div>
<div styleName='item-title'>
{note.title.trim().length > 0
? note.title
: <span styleName='item-title-empty'>Empty</span>
}
</div>
<div styleName='item-bottom'>
<div styleName='item-bottom-tagList'>
{note.tags.length > 0
? TagElementList(note.tags)
: ''
}
</div>
</div>
{note.type === 'SNIPPET_NOTE'
? <i styleName='item-title-icon' className='fa fa-fw fa-code' />
: <i styleName='item-title-icon' className='fa fa-fw fa-file-text-o' />
}
{note.isStarred
? <i styleName='item-star' className='fa fa-star' /> : ''
}
</div>
</div>
)
NoteItem.propTypes = {
isActive: PropTypes.bool.isRequired,
dateDisplay: PropTypes.string.isRequired,
note: PropTypes.shape({
storage: PropTypes.string.isRequired,
key: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
title: PropTypes.string.isrequired,
tags: PropTypes.array,
isStarred: PropTypes.bool.isRequired
}),
handleNoteClick: PropTypes.func.isRequired,
handleNoteContextMenu: PropTypes.func.isRequired
}
export default CSSModules(NoteItem, styles)

View File

@@ -0,0 +1,168 @@
$control-height = 30px
.root
absolute left bottom
top $topBar-height - 1
background-color $ui-noteList-backgroundColor
.item
position relative
padding 0 25px
user-select none
cursor pointer
background-color $ui-noteList-backgroundColor
transition background-color 0.15s
&:hover
background-color alpha($ui-active-color, 20%)
&:active
background-color $ui-active-color
color white
.item-title
.item-title-empty
.item-bottom-tagList-empty
.item-bottom-time
.item-title-icon
color white
.item-bottom-tagList-item
background-color transparent
color white
.item-wrapper
padding 20px 0
border-bottom $ui-border
.item--active
@extend .item
background-color $ui-active-color
color white
.item-title
.item-title-empty
.item-bottom-tagList-empty
.item-bottom-time
.item-title-icon
color white
.item-bottom-tagList-item
background-color transparent
color white
.item-wrapper
border-color transparent
&:hover
background-color $ui-active-color
.item-title
font-size 14px
height 40px
box-sizing border-box
line-height 24px
padding-top 5px
padding-bottom 20px
overflow ellipsis
color $ui-text-color
.item-title-icon
position absolute
top 20px
right 25px
font-size 14px
color $ui-inactive-text-color
.item-title-empty
font-weight normal
color $ui-inactive-text-color
.item-bottom
position relative
bottom 0px
margin-top 2px
height 20px
font-size 12px
line-height 20px
overflow ellipsis
display flex
.item-bottom-tagList
flex 1
overflow ellipsis
line-height 20px
color #FFFFFF
.item-bottom-tagList-item
font-size 12px
margin-right 8px
padding 0 10px
height 20px
box-sizing border-box
border-radius 20px
vertical-align middle
background-color $ui-tag-backgroundColor
color #FFFFFF
.item-bottom-tagList-empty
color $ui-inactive-text-color
vertical-align middle
font-size 10px
margin-left 5px
.item-bottom-time
color $ui-inactive-text-color
font-size 12px
.item-star
position absolute
top 20px
right 29px
width 34px
height 34px
color $ui-favorite-star-button-color
font-size 14px
padding 0
border-radius 17px
body[data-theme="dark"]
.root
border-color $ui-dark-borderColor
background-color $ui-dark-noteList-backgroundColor
.item
border-color $ui-dark-borderColor
background-color $ui-dark-noteList-backgroundColor
&:active
background-color $ui-active-color
&:hover
background-color alpha($ui-active-color, 20%)
.item-wrapper
border-color $ui-dark-borderColor
.item--active
@extend .item
border-color $ui-dark-borderColor
background-color $ui-active-color
.item-wrapper
border-color transparent
.item-title
color white
.item-bottom-tagList-item
background-color transparent
color white
.item-bottom-tagList-empty
color white
&:hover
background-color $ui-active-color
.item-title
color $ui-dark-text-color
.item-title-icon
color $ui-darkinactive-text-color
.item-title-empty
color $ui-dark-inactive-text-color
.item-bottom-tagList-item
background-color $ui-dark-tag-backgroundColor
color $ui-dark-text-color
.item-bottom-tagList-empty
color $ui-inactive-text-color
vertical-align middle

View File

@@ -0,0 +1,49 @@
/**
* @fileoverview Note item component with simple display mode.
*/
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './NoteItemSimple.styl'
/**
* @description Note item component when using simple display mode.
* @param {boolean} isActive
* @param {Object} note
* @param {Function} handleNoteClick
* @param {Function} handleNoteContextMenu
*/
const NoteItemSimple = ({ isActive, note, handleNoteClick, handleNoteContextMenu }) => (
<div styleName={isActive
? 'item-simple--active'
: 'item-simple'
}
key={`${note.storage}-${note.key}`}
onClick={e => handleNoteClick(e, `${note.storage}-${note.key}`)}
onContextMenu={e => handleNoteContextMenu(e, `${note.storage}-${note.key}`)}
>
<div styleName='item-simple-title'>
{note.type === 'SNIPPET_NOTE'
? <i styleName='item-simple-title-icon' className='fa fa-fw fa-code' />
: <i styleName='item-simple-title-icon' className='fa fa-fw fa-file-text-o' />
}
{note.title.trim().length > 0
? note.title
: <span styleName='item-simple-title-empty'>Empty</span>
}
</div>
</div>
)
NoteItemSimple.propTypes = {
isActive: PropTypes.bool.isRequired,
note: PropTypes.shape({
storage: PropTypes.string.isRequired,
key: PropTypes.string.isRequired,
type: PropTypes.string.isRequired,
title: PropTypes.string.isrequired
}),
handleNoteClick: PropTypes.func.isRequired,
handleNoteContextMenu: PropTypes.func.isRequired
}
export default CSSModules(NoteItemSimple, styles)

View File

@@ -0,0 +1,89 @@
$control-height = 30px
.root
absolute left bottom
top $topBar-height - 1
background-color $ui-noteList-backgroundColor
.item-simple
position relative
padding 0 25px
user-select none
cursor pointer
background-color $ui-noteList-backgroundColor
transition background-color 0.15s
&:hover
background-color alpha($ui-active-color, 20%)
&:active
background-color $ui-active-color
color white
.item-simple-title
.item-simple-title-empty
.item-simple-title-icon
color white
.item-simple--active
@extend .item-simple
background-color $ui-active-color
color white
.item-simple-title
.item-simple-title-empty
border-color transparent
color white
.item-simple-title-icon
color white
&:hover
background-color $ui-active-color
.item-simple-title
font-size 14px
height 40px
box-sizing border-box
line-height 24px
padding-top 8px
overflow ellipsis
color $ui-text-color
border-bottom $ui-border
.item-simple-title-icon
font-size 12px
color $ui-inactive-text-color
padding-right 6px
.item-simple-title-empty
font-weight normal
color $ui-inactive-text-color
body[data-theme="dark"]
.root
border-color $ui-dark-borderColor
background-color $ui-dark-noteList-backgroundColor
.item-simple
border-color $ui-dark-borderColor
background-color $ui-dark-noteList-backgroundColor
&:active
background-color $ui-active-color
&:hover
background-color alpha($ui-active-color, 20%)
.item-simple--active
@extend .item-simple
border-color $ui-dark-borderColor
background-color $ui-active-color
.item-simple-title
.item-simple-title-empty
color white
border-color transparent
&:hover
background-color $ui-active-color
.item-simple-title
color $ui-dark-text-color
border-color $ui-dark-borderColor
.item-simple-title-icon
color $ui-darkinactive-text-color
.item-simple-title-empty
color $ui-dark-inactive-text-color

View File

@@ -12,7 +12,7 @@ export default class ProfileImage extends React.Component {
className={className} className={className}
width={this.props.size} width={this.props.size}
height={this.props.size} height={this.props.size}
src={src}/> src={src} />
) )
} }
} }

View File

@@ -0,0 +1,44 @@
/**
* @fileoverview Filter for all notes.
*/
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './SideNavFilter.styl'
/**
* @param {boolean} isFolded
* @param {boolean} isHomeActive
* @param {Function} handleAllNotesButtonClick
* @param {boolean} isStarredActive
* @param {Function} handleStarredButtonClick
* @return {React.Component}
*/
const SideNavFilter = ({
isFolded, isHomeActive, handleAllNotesButtonClick,
isStarredActive, handleStarredButtonClick
}) => (
<div styleName={isFolded ? 'menu--folded' : 'menu'}>
<button styleName={isHomeActive ? 'menu-button--active' : 'menu-button'}
onClick={handleAllNotesButtonClick}
>
<i className='fa fa-book fa-fw' />
<span styleName='menu-button-label'>All Notes</span>
</button>
<button styleName={isStarredActive ? 'menu-button--active' : 'menu-button'}
onClick={handleStarredButtonClick}
>
<i className='fa fa-star fa-fw' />
<span styleName='menu-button-label'>Starred</span>
</button>
</div>
)
SideNavFilter.propTypes = {
isFolded: PropTypes.bool,
isHomeActive: PropTypes.bool.isRequired,
handleAllNotesButtonClick: PropTypes.func.isRequired,
isStarredActive: PropTypes.bool.isRequired,
handleStarredButtonClick: PropTypes.func.isRequired
}
export default CSSModules(SideNavFilter, styles)

View File

@@ -0,0 +1,58 @@
.menu
margin-bottom 30px
.menu-button
navButtonColor()
height 32px
padding 0 15px
font-size 14px
width 100%
text-align left
overflow ellipsis
.menu-button--active
@extend .menu-button
background-color $ui-button--active-backgroundColor
color $ui-button--active-color
&:hover
background-color $ui-button--active-backgroundColor
.menu-button-label
margin-left 5px
.menu--folded
@extend .menu
.menu-button, .menu-button--active
text-align center
&:hover .menu-button-label
transition opacity 0.15s
opacity 1
.menu-button-label
position fixed
display inline-block
height 32px
left 44px
padding 0 10px
margin-top -8px
margin-left 0
overflow ellipsis
background-color $ui-tooltip-backgroundColor
z-index 10
color white
line-height 32px
border-top-right-radius 2px
border-bottom-right-radius 2px
pointer-events none
opacity 0
font-size 12px
body[data-theme="dark"]
.menu-button
navDarkButtonColor()
.menu-button--active
@extend .menu-button
background-color $ui-dark-button--active-backgroundColor
color $ui-dark-button--active-color
&:hover
background-color $ui-dark-button--active-backgroundColor

View File

@@ -1,4 +1,4 @@
import React, { PropTypes } from 'react' import React from 'react'
import CSSModules from 'browser/lib/CSSModules' import CSSModules from 'browser/lib/CSSModules'
import styles from './SnippetTab.styl' import styles from './SnippetTab.styl'
import context from 'browser/lib/context' import context from 'browser/lib/context'
@@ -117,7 +117,7 @@ class SnippetTab extends React.Component {
<button styleName='deleteButton' <button styleName='deleteButton'
onClick={(e) => this.handleDeleteButtonClick(e)} onClick={(e) => this.handleDeleteButtonClick(e)}
> >
<i className='fa fa-times'/> <i className='fa fa-times' />
</button> </button>
} }
</div> </div>

View File

@@ -2,9 +2,6 @@
position relative position relative
flex 1 flex 1
overflow hidden overflow hidden
border-right $ui-border
&:last-child
border-right none
&:hover &:hover
.deleteButton .deleteButton
color $ui-inactive-text-color color $ui-inactive-text-color
@@ -13,11 +10,11 @@
&:active &:active
color white color white
background-color $ui-active-color background-color $ui-active-color
.root--active .root--active
@extend .root @extend .root
min-width 100px min-width 100px
.button border-bottom $ui-border
border-color $brand-color
.button .button
width 100% width 100%
@@ -31,8 +28,6 @@
border-left 4px solid transparent border-left 4px solid transparent
&:hover &:hover
background-color $ui-button--hover-backgroundColor background-color $ui-button--hover-backgroundColor
&:active, &:active:hover
border-color $brand-color
.deleteButton .deleteButton
position absolute position absolute
@@ -71,8 +66,6 @@ body[data-theme="dark"]
.root--active .root--active
color $ui-dark-text-color color $ui-dark-text-color
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
.button
border-color $brand-color
&:hover &:hover
background-color $ui-dark-button--hover-backgroundColor background-color $ui-dark-button--hover-backgroundColor
.deleteButton .deleteButton
@@ -92,10 +85,6 @@ body[data-theme="dark"]
&:hover &:hover
color white color white
background-color $ui-dark-button--hover-backgroundColor background-color $ui-dark-button--hover-backgroundColor
&:active
color $ui-dark-button--active-color
&:active, &:active:hover
color $ui-dark-button--active-color
.input .input
background-color $ui-dark-button--hover-backgroundColor background-color $ui-dark-button--hover-backgroundColor

View File

@@ -0,0 +1,58 @@
/**
* @fileoverview Micro component for showing storage.
*/
import React, { PropTypes } from 'react'
import styles from './StorageItem.styl'
import CSSModules from 'browser/lib/CSSModules'
import { isNumber } from 'lodash'
/**
* @param {boolean} isActive
* @param {Function} handleButtonClick
* @param {Function} handleContextMenu
* @param {string} folderName
* @param {string} folderColor
* @param {boolean} isFolded
* @param {number} noteCount
* @return {React.Component}
*/
const StorageItem = ({
isActive, handleButtonClick, handleContextMenu, folderName,
folderColor, isFolded, noteCount
}) => (
<button styleName={isActive
? 'folderList-item--active'
: 'folderList-item'
}
onClick={handleButtonClick}
onContextMenu={handleContextMenu}
>
<span styleName={isFolded
? 'folderList-item-name--folded' : 'folderList-item-name'
}
style={{borderColor: folderColor}}
>
{isFolded ? folderName.substring(0, 1) : folderName}
</span>
{(!isFolded && isNumber(noteCount)) &&
<span styleName='folderList-item-noteCount'>{noteCount}</span>
}
{isFolded &&
<span styleName='folderList-item-tooltip'>
{folderName}
</span>
}
</button>
)
StorageItem.propTypes = {
isActive: PropTypes.bool.isRequired,
handleButtonClick: PropTypes.func,
handleContextMenu: PropTypes.func,
folderName: PropTypes.string.isRequired,
folderColor: PropTypes.string,
isFolded: PropTypes.bool.isRequired,
noteCount: PropTypes.number
}
export default CSSModules(StorageItem, styles)

View File

@@ -0,0 +1,70 @@
.root
width 100%
user-select none
.folderList-item
display flex
width 100%
height 26px
background-color transparent
color $ui-inactive-text-color
padding 0
margin-bottom 5px
text-align left
border none
overflow ellipsis
font-size 14px
&:first-child
margin-top 0
&:hover
background-color $ui-button--hover-backgroundColor
&:active
color $ui-button--active-color
background-color $ui-button--active-backgroundColor
.folderList-item--active
@extend .folderList-item
color $ui-button--active-color
background-color $ui-button--active-backgroundColor
&:hover
color $ui-button--active-color
background-color $ui-button--active-backgroundColor
.folderList-item-name
display block
flex 1
padding 0 30px
height 26px
line-height 26px
border-width 0 0 0 3px
border-style solid
border-color transparent
overflow hidden
text-overflow ellipsis
.folderList-item-noteCount
float right
line-height 26px
padding-right 15px
font-size 12px
.folderList-item-tooltip
tooltip()
position fixed
padding 0 10px
left 44px
z-index 10
pointer-events none
opacity 0
border-top-right-radius 2px
border-bottom-right-radius 2px
height 26px
line-height 26px
.folderList-item:hover, .folderList-item--active:hover
.folderList-item-tooltip
opacity 1
.folderList-item-name--folded
@extend .folderList-item-name
padding-left 14px

View File

@@ -55,6 +55,7 @@ body
line-height 1.6 line-height 1.6
overflow-x hidden overflow-x hidden
user-select all user-select all
background-color $ui-noteDetail-backgroundColor
.katex .katex
font 400 1.2em 'KaTeX_Main' font 400 1.2em 'KaTeX_Main'
line-height 1.2em line-height 1.2em
@@ -68,6 +69,12 @@ body
padding 5px padding 5px
margin -5px margin -5px
border-radius 5px border-radius 5px
.flowchart-error, .sequence-error
background-color errorBackgroundColor
color errorTextColor
padding 5px
border-radius 5px
justify-content left
li li
label.taskListItem label.taskListItem
margin-left -2em margin-left -2em
@@ -191,7 +198,7 @@ code
padding 0.2em 0.4em padding 0.2em 0.4em
background-color #f7f7f7 background-color #f7f7f7
border-radius 3px border-radius 3px
font-size 0.85em font-size 1em
text-decoration none text-decoration none
margin-right 2px margin-right 2px
pre pre
@@ -200,26 +207,40 @@ pre
border-radius 5px border-radius 5px
overflow-x auto overflow-x auto
margin 0 0 1em margin 0 0 1em
line-height 1.35 display flex
line-height 1.4em
&.flowchart, &.sequence
display flex
justify-content center
background-color white
&.CodeMirror
height initial
&>code
flex 1
overflow-x auto
code code
margin 0
background-color inherit background-color inherit
margin 0
padding 0 padding 0
border none border none
border-radius 0 border-radius 0
pre
border none
margin -5px
&>span.lineNumber &>span.lineNumber
display none display none
float left font-size 1em
font-size 0.85em padding 0.5em 0
margin 0 0.5em 0 -0.5em margin -0.5em 0.5em -0.5em -0.5em
border-right 1px solid border-right 1px solid
text-align right text-align right
border-top-left-radius 4px
border-bottom-left-radius 4px
&.CodeMirror-gutters
position initial
top initial
left initial
min-height 0 !important
&>span &>span
display block display block
padding 0 .5em 0 1em padding 0 .5em 0
table table
display block display block
width 100% width 100%
@@ -253,13 +274,14 @@ table
themeDarkBackground = darken(#21252B, 10%) themeDarkBackground = darken(#21252B, 10%)
themeDarkText = #DDDDDD themeDarkText = #DDDDDD
themeDarkBorder = lighten(themeDarkBackground, 20%) themeDarkBorder = lighten(themeDarkBackground, 20%)
themeDarkPreview = #282C34 themeDarkPreview = $ui-dark-noteDetail-backgroundColor
themeDarkTableOdd = themeDarkPreview themeDarkTableOdd = themeDarkPreview
themeDarkTableEven = darken(themeDarkPreview, 10%) themeDarkTableEven = darken(themeDarkPreview, 10%)
themeDarkTableHead = themeDarkTableEven themeDarkTableHead = themeDarkTableEven
themeDarkTableBorder = themeDarkBorder themeDarkTableBorder = themeDarkBorder
themeDarkModalButtonDefault = themeDarkPreview themeDarkModalButtonDefault = themeDarkPreview
themeDarkModalButtonDanger = #BF360C themeDarkModalButtonDanger = #BF360C
body[data-theme="dark"] body[data-theme="dark"]
color themeDarkText color themeDarkText
border-color themeDarkBorder border-color themeDarkBorder
@@ -269,7 +291,7 @@ body[data-theme="dark"]
code code
border-color darken(themeDarkBorder, 10%) border-color darken(themeDarkBorder, 10%)
background-color lighten(themeDarkPreview, 5%) background-color lighten(themeDarkPreview, 10%)
pre pre
border-color lighten(#21252B, 20%) border-color lighten(#21252B, 20%)

View File

@@ -21,6 +21,7 @@ $list-width = 250px
outline none outline none
text-align center text-align center
background-color transparent background-color transparent
.result .result
absolute left right bottom absolute left right bottom
top $search-height top $search-height
@@ -32,7 +33,7 @@ $list-width = 250px
background-color $ui-backgroundColor background-color $ui-backgroundColor
.result-nav-filter .result-nav-filter
margin-bottom 5px margin-bottom 10px
.result-nav-filter-option .result-nav-filter-option
height 25px height 25px
@@ -62,7 +63,7 @@ $list-width = 250px
.result-nav-storageList .result-nav-storageList
absolute bottom left right absolute bottom left right
top 80px + 32px + 10px top 80px + 32px + 10px + 10px
overflow-y auto overflow-y auto
.result-list .result-list
@@ -70,15 +71,15 @@ $list-width = 250px
absolute top bottom absolute top bottom
left $nav-width left $nav-width
width $list-width width $list-width
border-width 0 1px
border-style solid
border-color $ui-borderColor
box-sizing border-box box-sizing border-box
overflow-y auto overflow-y auto
box-shadow 2px 0 15px -8px #b1b1b1
z-index 1
.result-detail .result-detail
absolute top bottom right absolute top bottom right
left $nav-width + $list-width left $nav-width + $list-width
background-color $ui-noteDetail-backgroundColor
body[data-theme="dark"] body[data-theme="dark"]
.root .root
@@ -104,7 +105,10 @@ body[data-theme="dark"]
.result-list .result-list
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
box-shadow none
top 0
.result-detail .result-detail
absolute top bottom right absolute top bottom right
left $nav-width + $list-width left $nav-width + $list-width
background-color $ui-dark-noteDetail-backgroundColor

View File

@@ -1,4 +1,4 @@
import React, { PropTypes } from 'react' import React from 'react'
import CSSModules from 'browser/lib/CSSModules' import CSSModules from 'browser/lib/CSSModules'
import styles from './NoteDetail.styl' import styles from './NoteDetail.styl'
import MarkdownPreview from 'browser/components/MarkdownPreview' import MarkdownPreview from 'browser/components/MarkdownPreview'
@@ -97,9 +97,7 @@ class NoteDetail extends React.Component {
let { note, config } = this.props let { note, config } = this.props
if (note == null) { if (note == null) {
return ( return (
<div styleName='root'> <div styleName='root' />
</div>
) )
} }
@@ -154,6 +152,7 @@ class NoteDetail extends React.Component {
fontSize={editorFontSize} fontSize={editorFontSize}
indentType={config.editor.indentType} indentType={config.editor.indentType}
indentSize={editorIndentSize} indentSize={editorIndentSize}
keyMap={config.editor.keyMap}
readOnly readOnly
ref={'code-' + index} ref={'code-' + index}
/> />
@@ -185,11 +184,13 @@ class NoteDetail extends React.Component {
return ( return (
<MarkdownPreview styleName='root' <MarkdownPreview styleName='root'
theme={config.ui.theme}
fontSize={config.preview.fontSize} fontSize={config.preview.fontSize}
fontFamily={config.preview.fontFamily} fontFamily={config.preview.fontFamily}
codeBlockTheme={config.preview.codeBlockTheme} codeBlockTheme={config.preview.codeBlockTheme}
codeBlockFontFamily={config.editor.fontFamily} codeBlockFontFamily={config.editor.fontFamily}
lineNumber={config.preview.lineNumber} lineNumber={config.preview.lineNumber}
indentSize={editorIndentSize}
value={note.content} value={note.content}
/> />
) )

View File

@@ -1,12 +1,16 @@
@import('../main/Detail/DetailVars.styl')
.root .root
absolute top bottom left right absolute top bottom left right
width 100% left $note-detail-left-margin
right $note-detail-right-margin
height 100% height 100%
width 365px
background-color $ui-noteDetail-backgroundColor
.description .description
absolute top left right absolute top left right
height 80px height 80px
border-bottom $ui-border
box-sizing border-box box-sizing border-box
.description-textarea .description-textarea
@@ -18,52 +22,43 @@
padding 10px padding 10px
line-height 1.6 line-height 1.6
box-sizing border-box box-sizing border-box
background-color $ui-noteDetail-backgroundColor
.tabList .tabList
absolute left right absolute left right
top 80px top 80px
box-sizing border-box box-sizing border-box
height 30px height 30px
border-bottom $ui-border
display flex display flex
background-color $ui-backgroundColor background-color $ui-noteDetail-backgroundColor
.tabList-item .tabList-item
position relative position relative
flex 1 flex 1
border-right $ui-border overflow hidden
&:hover
background-color $ui-button--hover-backgroundColorg
.tabList-item--active .tabList-item--active
@extend .tabList-item @extend .tabList-item
.tabList-item-button border-bottom $ui-border
border-color $brand-color
.tabList-item-button .tabList-item-button
width 100% width 100%
height 29px height 29px
navButtonColor() overflow ellipsis
outline none text-align left
border-left 4px solid transparent padding-right 30px
padding-left 10px
.tabList-item-deleteButton
position absolute
top 5px
height 20px
right 5px
width 20px
text-align center
border none border none
padding 0
color transparent
background-color transparent background-color transparent
border-radius 2px transition 0.15s
.tabList-plusButton &:hover
navButtonColor() background-color $ui-button--hover-backgroundColor
width 30px
.tabView .tabView
absolute left right bottom absolute left right bottom
top 110px top 130px
.tabView-content .tabView-content
absolute top left right bottom absolute top left right bottom
@@ -72,38 +67,31 @@
width 100% width 100%
body[data-theme="dark"] body[data-theme="dark"]
.root
background-color $ui-dark-noteDetail-backgroundColor
.description .description
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
background-color $ui-dark-noteDetail-backgroundColor
.description-textarea .description-textarea
background-color $ui-dark-button--hover-backgroundColor background-color $ui-dark-noteDetail-backgroundColor
color white color white
.tabList .tabList
background-color $ui-button--active-backgroundColor background-color $ui-dark-noteDetail-backgroundColor
border-bottom-color $ui-dark-borderColor
background-color $ui-dark-backgroundColor
.tabList-item .tabList-item
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
&:hover &:hover
background-color $ui-dark-button--hover-backgroundColor background-color $ui-dark-button--hover-backgroundColor
.tabList-item--active
border-color $ui-dark-borderColor
.tabList-item-button
border-color $brand-color
.tabList-item-button
navDarkButtonColor()
border-left 4px solid transparent
.tabList-plusButton
navDarkButtonColor()
.tabView-top .tabList-item-button
border-color $ui-dark-borderColor border none
.tabView-top-name
border-color $ui-dark-borderColor
color $ui-dark-text-color color $ui-dark-text-color
background-color $ui-dark-button--hover-backgroundColor background-color transparent
.tabView-top-mode transition color background-color 0.15s
border-color $ui-dark-borderColor border-left 4px solid transparent
background-color $dark-default-button-background &:hover
color $ui-dark-inactive-text-color color white
background-color $ui-dark-button--hover-backgroundColor

View File

@@ -1,85 +0,0 @@
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './NoteItem.styl'
import moment from 'moment'
import _ from 'lodash'
class NoteItem extends React.Component {
constructor (props) {
super(props)
this.state = {
}
}
handleClick (e) {
this.props.onClick(e)
}
render () {
let { note, folder, storage, isActive } = this.props
let tagList = _.isArray(note.tags)
? note.tags.map((tag) => {
return (
<span styleName='bottom-tagList-item'
key={tag}>
{tag}
</span>
)
})
: []
return (
<div styleName={isActive
? 'root--active'
: 'root'
}
key={note.storage + '-' + note.key}
onClick={(e) => this.handleClick(e)}
>
<div styleName='info'>
<div styleName='info-left'>
<span styleName='info-left-folder'
style={{borderColor: folder.color}}
>
{folder.name}
<span styleName='info-left-folder-surfix'>in {storage.name}</span>
</span>
</div>
</div>
<div styleName='title'>
{note.type === 'SNIPPET_NOTE'
? <i styleName='title-icon' className='fa fa-fw fa-code'/>
: <i styleName='title-icon' className='fa fa-fw fa-file-text-o'/>
}
{note.title.trim().length > 0
? note.title
: <span styleName='title-empty'>Empty</span>
}
</div>
<div styleName='bottom'>
<i styleName='bottom-tagIcon'
className='fa fa-tags fa-fw'
/>
<div styleName='bottom-tagList'>
{tagList.length > 0
? tagList
: <span styleName='bottom-tagList-empty'>Not tagged yet</span>
}
</div>
<div styleName='bottom-time'>
{moment(note.updatedAt).fromNow()}
</div>
</div>
</div>
)
}
}
NoteItem.propTypes = {
}
export default CSSModules(NoteItem, styles)

View File

@@ -1,179 +0,0 @@
.root
position relative
border-bottom $ui-border
padding 2px 5px
user-select none
cursor pointer
transition background-color 0.15s
&:hover
background-color alpha($ui-active-color, 20%)
.root--active
@extend .root
background-color $ui-active-color
&:hover
background-color $ui-active-color
color white
.info-left-folder
.info-left-folder-surfix
.title
.title-icon
.title-empty
.bottom-tagIcon
.bottom-tagList-item
.bottom-tagList-empty
.bottom-time
color white
.bottom-tagList-item
color white
background-color transparent
.border
absolute top bottom left right
border-style solid
border-width 2px
border-color transparent
transition 0.15s
.info
height 20px
clearfix()
font-size 12px
color $ui-inactive-text-color
line-height 20px
overflow-y hidden
.info-left
float left
overflow ellipsis
.info-left-folder
border-left 4px solid transparent
padding 2px 5px
color $ui-text-color
.info-left-folder-surfix
font-size 10px
margin-left 5px
color $ui-inactive-text-color
.info-right
float right
.title
height 24px
box-sizing border-box
line-height 24px
height 20px
line-height 20px
padding 0 5px 0 0
overflow ellipsis
color $ui-text-color
.title-icon
font-size 12px
color $ui-inactive-text-color
padding-right 3px
.title-empty
font-weight normal
color $ui-inactive-text-color
.bottom
margin-top 2px
height 20px
font-size 12px
line-height 20px
overflow ellipsis
display flex
.bottom-tagIcon
vertical-align middle
color $ui-button-color
height 20px
line-height 20px
.bottom-tagList
flex 1
overflow ellipsis
line-height 20px
.bottom-tagList-item
margin 0 4px
padding 0 4px
height 20px
box-sizing border-box
border-radius 3px
vertical-align middle
border-style solid
border-color $ui-button--focus-borderColor
border-width 0 0 0 3px
background-color $ui-backgroundColor
color $ui-text-color
transition 0.15s
.bottom-tagList-empty
color $ui-inactive-text-color
vertical-align middle
font-size 10px
margin-left 5px
.bottom-time
color $ui-inactive-text-color
margin-left 5px
font-size 10px
body[data-theme="dark"]
.root
border-color $ui-dark-borderColor
.root--active
@extend .root
border-color $ui-dark-borderColor
&:hover
background-color $ui-active-color
.info-left-folder
.info-left-folder-surfix
.title
.title-icon
.title-empty
.bottom-tagIcon
.bottom-tagList-item
.bottom-tagList-empty
.bottom-time
color white
.bottom-tagList-item
color white
background-color transparent
.info
color $ui-dark-inactive-text-color
.info-left-folder
color $ui-dark-text-color
.info-left-folder-surfix
color $ui-dark-inactive-text-color
.title
color $ui-dark-text-color
.title-icon
color $ui-dark-inactive-text-color
.title-empty
color $ui-dark-inactive-text-color
.tagList-empty
color $ui-dark-inactive-text-color
.bottom-tagIcon
color $ui-dark-button-color
.bottom-tagList-item
color $ui-dark-text-color
background-color $ui-dark-backgroundColor
.bottom-tagList-empty
color $ui-dark-inactive-text-color
.bottom-time
color $ui-dark-inactive-text-color

View File

@@ -1,6 +1,6 @@
import React, { PropTypes } from 'react' import React from 'react'
import NoteItem from './NoteItem' import NoteItem from 'browser/components/NoteItem'
import _ from 'lodash' import moment from 'moment'
class NoteList extends React.Component { class NoteList extends React.Component {
constructor (props) { constructor (props) {
@@ -54,21 +54,23 @@ class NoteList extends React.Component {
} }
render () { render () {
let { storageMap, notes, index } = this.props let { notes, index } = this.props
let notesList = notes let notesList = notes
.slice(0, 10 + 10 * this.state.range) .slice(0, 10 + 10 * this.state.range)
.map((note, _index) => { .map((note, _index) => {
let storage = storageMap[note.storage] const isActive = (index === _index)
let folder = _.find(storage.folders, {key: note.folder}) const key = `${note.storage}-${note.key}`
const dateDisplay = moment(note.updatedAt).fromNow()
return ( return (
<NoteItem <NoteItem
isActive={isActive}
note={note} note={note}
key={`${note.storage}-${note.key}`} dateDisplay={dateDisplay}
storage={storage} key={key}
folder={folder} handleNoteClick={(e) => this.props.handleNoteClick(e, _index)}
isActive={index === _index} handleNoteContextMenu={() => ''}
onClick={(e) => this.props.handleNoteClick(e, _index)}
/> />
) )
}) })

View File

@@ -1,6 +1,7 @@
import React, { PropTypes } from 'react' import React from 'react'
import CSSModules from 'browser/lib/CSSModules' import CSSModules from 'browser/lib/CSSModules'
import styles from './StorageSection.styl' import styles from './StorageSection.styl'
import StorageItem from 'browser/components/StorageItem'
class StorageSection extends React.Component { class StorageSection extends React.Component {
constructor (props) { constructor (props) {
@@ -30,20 +31,17 @@ class StorageSection extends React.Component {
render () { render () {
let { storage, filter } = this.props let { storage, filter } = this.props
let folderList = storage.folders let folderList = storage.folders
.map((folder) => { .map(folder => (
return ( <StorageItem
<button styleName={filter.type === 'FOLDER' && filter.folder === folder.key && filter.storage === storage.key key={folder.key}
? 'folderList-item--active' isActive={filter.type === 'FOLDER' && filter.folder === folder.key && filter.storage === storage.key}
: 'folderList-item' handleButtonClick={(e) => this.handleFolderClick(e, folder)}
} folderName={folder.name}
style={{borderColor: folder.color}} folderColor={folder.color}
key={folder.key} isFolded={false}
onClick={(e) => this.handleFolderClick(e, folder)} />
> ))
{folder.name}
</button>
)
})
return ( return (
<div styleName='root'> <div styleName='root'>
<div styleName='header'> <div styleName='header'>

View File

@@ -2,13 +2,13 @@ import React, { PropTypes } from 'react'
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import { connect, Provider } from 'react-redux' import { connect, Provider } from 'react-redux'
import _ from 'lodash' import _ from 'lodash'
import ipc from './ipcClient'
import store from './store' import store from './store'
import CSSModules from 'browser/lib/CSSModules' import CSSModules from 'browser/lib/CSSModules'
import styles from './FinderMain.styl' import styles from './FinderMain.styl'
import StorageSection from './StorageSection' import StorageSection from './StorageSection'
import NoteList from './NoteList' import NoteList from './NoteList'
import NoteDetail from './NoteDetail' import NoteDetail from './NoteDetail'
import SideNavFilter from 'browser/components/SideNavFilter'
require('!!style!css!stylus?sourceMap!../main/global.styl') require('!!style!css!stylus?sourceMap!../main/global.styl')
require('../lib/customMeta') require('../lib/customMeta')
@@ -307,18 +307,12 @@ class FinderMain extends React.Component {
/> Only Markdown</label> /> Only Markdown</label>
</div> </div>
</div> </div>
<button styleName={filter.type === 'ALL' <SideNavFilter
? 'result-nav-menu--active' isHomeActive={filter.type === 'ALL'}
: 'result-nav-menu' handleAllNotesButtonClick={(e) => this.handleAllNotesButtonClick(e)}
} isStarredActive={filter.type === 'STARRED'}
onClick={(e) => this.handleAllNotesButtonClick(e)} handleStarredButtonClick={(e) => this.handleStarredButtonClick(e)}
><i className='fa fa-files-o fa-fw'/> All Notes</button> />
<button styleName={filter.type === 'STARRED'
? 'result-nav-menu--active'
: 'result-nav-menu'
}
onClick={(e) => this.handleStarredButtonClick(e)}
><i className='fa fa-star fa-fw'/> Starred</button>
<div styleName='result-nav-storageList'> <div styleName='result-nav-storageList'>
{storageList} {storageList}
</div> </div>
@@ -356,7 +350,7 @@ function refreshData () {
ReactDOM.render(( ReactDOM.render((
<Provider store={store}> <Provider store={store}>
<Finder/> <Finder />
</Provider> </Provider>
), document.getElementById('content'), function () { ), document.getElementById('content'), function () {
refreshData() refreshData()

View File

@@ -1,21 +0,0 @@
import superagent from 'superagent'
import superagentPromise from 'superagent-promise'
export const SERVER_URL = 'https://b00st.io/'
// export const SERVER_URL = 'http://localhost:3333/'
export const request = superagentPromise(superagent, Promise)
export function shareViaPublicURL (input) {
return request
.post(SERVER_URL + 'apis/share')
// .set({
// Authorization: 'Bearer ' + auth.token()
// })
.send(input)
}
export default {
SERVER_URL,
shareViaPublicURL
}

View File

@@ -1,4 +1,3 @@
import CodeMirror from 'codemirror' import CodeMirror from 'codemirror'
import _ from 'lodash'
CodeMirror.modeInfo.push({name: 'Stylus', mime: 'text/x-styl', mode: 'stylus', ext: ['styl']}) CodeMirror.modeInfo.push({name: 'Stylus', mime: 'text/x-styl', mode: 'stylus', ext: ['styl'], alias: ['styl']})

View File

@@ -0,0 +1,18 @@
/**
* @fileoverview Formatting date string.
*/
import moment from 'moment'
/**
* @description Return date string. For example, 'Sep.9, 2016 12:00'.
* @param {mixed}
* @return {string}
*/
export function getLastUpdated (date) {
const m = moment(date)
if (!m.isValid()) {
throw Error('Invalid argument.')
}
return m.format('MMM D, gggg H:mm')
}

View File

@@ -1,78 +0,0 @@
const hljsThemeList = [
{caption: 'Default', name: 'default'},
{caption: 'Agate', name: 'agate'},
{caption: 'Androidstudio', name: 'androidstudio'},
{caption: 'Arduino Light', name: 'arduino-light'},
{caption: 'Arta', name: 'arta'},
{caption: 'Ascetic', name: 'ascetic'},
{caption: 'Atelier Cave Dark', name: 'atelier-cave-dark'},
{caption: 'Atelier Cave Light', name: 'atelier-cave-light'},
{caption: 'Atelier Dune Dark', name: 'atelier-dune-dark'},
{caption: 'Atelier Dune Light', name: 'atelier-dune-light'},
{caption: 'Atelier Estuary Dark', name: 'atelier-estuary-dark'},
{caption: 'Atelier Estuary Light', name: 'atelier-estuary-light'},
{caption: 'Atelier Forest Dark', name: 'atelier-forest-dark'},
{caption: 'Atelier Forest Light', name: 'atelier-forest-light'},
{caption: 'Atelier Heath Dark', name: 'atelier-heath-dark'},
{caption: 'Atelier Heath Light', name: 'atelier-heath-light'},
{caption: 'Atelier Lakeside Dark', name: 'atelier-lakeside-dark'},
{caption: 'Atelier Lakeside Light', name: 'atelier-lakeside-light'},
{caption: 'Atelier Plateau Dark', name: 'atelier-plateau-dark'},
{caption: 'Atelier Plateau Light', name: 'atelier-plateau-light'},
{caption: 'Atelier Savanna Dark', name: 'atelier-savanna-dark'},
{caption: 'Atelier Savanna Light', name: 'atelier-savanna-light'},
{caption: 'Atelier Seaside Dark', name: 'atelier-seaside-dark'},
{caption: 'Atelier Seaside Light', name: 'atelier-seaside-light'},
{caption: 'Atelier Sulphurpool Dark', name: 'atelier-sulphurpool-dark'},
{caption: 'Atelier Sulphurpool Light', name: 'atelier-sulphurpool-light'},
{caption: 'Brown Paper', name: 'brown-paper'},
{caption: 'Codepen Embed', name: 'codepen-embed'},
{caption: 'Color Brewer', name: 'color-brewer'},
{caption: 'Dark', name: 'dark'},
{caption: 'Darkula', name: 'darkula'},
{caption: 'Docco', name: 'docco'},
{caption: 'Dracula', name: 'dracula'},
{caption: 'Far', name: 'far'},
{caption: 'Foundation', name: 'foundation'},
{caption: 'Github Gist', name: 'github-gist'},
{caption: 'Github', name: 'github'},
{caption: 'Googlecode', name: 'googlecode'},
{caption: 'Grayscale', name: 'grayscale'},
{caption: 'Gruvbox Dark', name: 'gruvbox.dark'},
{caption: 'Gruvbox Light', name: 'gruvbox.light'},
{caption: 'Hopscotch', name: 'hopscotch'},
{caption: 'Hybrid', name: 'hybrid'},
{caption: 'Idea', name: 'idea'},
{caption: 'Ir Black', name: 'ir-black'},
{caption: 'Kimbie Dark', name: 'kimbie.dark'},
{caption: 'Kimbie Light', name: 'kimbie.light'},
{caption: 'Magula', name: 'magula'},
{caption: 'Mono Blue', name: 'mono-blue'},
{caption: 'Monokai Sublime', name: 'monokai-sublime'},
{caption: 'Monokai', name: 'monokai'},
{caption: 'Obsidian', name: 'obsidian'},
{caption: 'Paraiso Dark', name: 'paraiso-dark'},
{caption: 'Paraiso Light', name: 'paraiso-light'},
{caption: 'Pojoaque', name: 'pojoaque'},
{caption: 'Qtcreator Dark', name: 'qtcreator_dark'},
{caption: 'Qtcreator Light', name: 'qtcreator_light'},
{caption: 'Railscasts', name: 'railscasts'},
{caption: 'Rainbow', name: 'rainbow'},
{caption: 'School Book', name: 'school-book'},
{caption: 'Solarized Dark', name: 'solarized-dark'},
{caption: 'Solarized Light', name: 'solarized-light'},
{caption: 'Sunburst', name: 'sunburst'},
{caption: 'Tomorrow Night Blue', name: 'tomorrow-night-blue'},
{caption: 'Tomorrow Night Bright', name: 'tomorrow-night-bright'},
{caption: 'Tomorrow Night Eighties', name: 'tomorrow-night-eighties'},
{caption: 'Tomorrow Night', name: 'tomorrow-night'},
{caption: 'Tomorrow', name: 'tomorrow'},
{caption: 'Vs', name: 'vs'},
{caption: 'Xcode', name: 'xcode'},
{caption: 'Xt 256', name: 'xt256'},
{caption: 'Zenburn', name: 'zenburn'}
]
export default function hljsTheme () {
return hljsThemeList
}

View File

@@ -1,7 +1,6 @@
import markdownit from 'markdown-it' import markdownit from 'markdown-it'
import emoji from 'markdown-it-emoji' import emoji from 'markdown-it-emoji'
import math from '@rokt33r/markdown-it-math' import math from '@rokt33r/markdown-it-math'
import hljs from 'highlight.js'
import _ from 'lodash' import _ from 'lodash'
const katex = window.katex const katex = window.katex
@@ -10,9 +9,9 @@ function createGutter (str) {
let lc = (str.match(/\n/g) || []).length let lc = (str.match(/\n/g) || []).length
let lines = [] let lines = []
for (let i = 1; i <= lc; i++) { for (let i = 1; i <= lc; i++) {
lines.push('<span>' + i + '</span>') lines.push('<span class="CodeMirror-linenumber">' + i + '</span>')
} }
return '<span class="lineNumber">' + lines.join('') + '</span>' return '<span class="lineNumber CodeMirror-gutters">' + lines.join('') + '</span>'
} }
var md = markdownit({ var md = markdownit({
@@ -21,19 +20,16 @@ var md = markdownit({
html: true, html: true,
xhtmlOut: true, xhtmlOut: true,
highlight: function (str, lang) { highlight: function (str, lang) {
if (lang && hljs.getLanguage(lang)) { if (lang === 'flowchart') {
try { return `<pre class="flowchart">${str}</pre>`
return '<pre class="hljs">' +
createGutter(str) +
'<code>' +
hljs.highlight(lang, str).value +
'</code></pre>'
} catch (e) {}
} }
return '<pre class="hljs">' + if (lang === 'sequence') {
return `<pre class="sequence">${str}</pre>`
}
return '<pre class="code">' +
createGutter(str) + createGutter(str) +
'<code>' + '<code class="' + lang + '">' +
str.replace(/\&/g, '&amp;').replace(/\</g, '&lt;').replace(/\>/g, '&gt;').replace(/\"/g, '&quot;') + str +
'</code></pre>' '</code></pre>'
} }
}) })
@@ -62,7 +58,7 @@ md.use(math, {
}) })
md.use(require('markdown-it-footnote')) md.use(require('markdown-it-footnote'))
// Override task item // Override task item
md.block.ruler.at('paragraph', function (state, startLine/*, endLine*/) { md.block.ruler.at('paragraph', function (state, startLine/*, endLine */) {
let content, terminate, i, l, token let content, terminate, i, l, token
let nextLine = startLine + 1 let nextLine = startLine + 1
let terminatorRules = state.md.block.ruler.getRules('paragraph') let terminatorRules = state.md.block.ruler.getRules('paragraph')
@@ -139,13 +135,13 @@ function strip (input) {
.replace(/`{3}.*\n/g, '') .replace(/`{3}.*\n/g, '')
.replace(/<(.*?)>/g, '$1') .replace(/<(.*?)>/g, '$1')
.replace(/^[=\-]{2,}\s*$/g, '') .replace(/^[=\-]{2,}\s*$/g, '')
.replace(/\[\^.+?\](\: .*?$)?/g, '') .replace(/\[\^.+?\](: .*?$)?/g, '')
.replace(/\s{0,2}\[.*?\]: .*?$/g, '') .replace(/\s{0,2}\[.*?\]: .*?$/g, '')
.replace(/\!\[.*?\][\[\(].*?[\]\)]/g, '') .replace(/!\[.*?\][\[\(].*?[\]\)]/g, '')
.replace(/\[(.*?)\][\[\(].*?[\]\)]/g, '$1') .replace(/\[(.*?)\][\[\(].*?[\]\)]/g, '$1')
.replace(/>/g, '') .replace(/>/g, '')
.replace(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/g, '') .replace(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/g, '')
.replace(/^\#{1,6}\s*([^#]*)\s*(\#{1,6})?/gm, '$1') .replace(/^#{1,6}\s*([^#]*)\s*(#{1,6})?/gm, '$1')
.replace(/([\*_]{1,3})(\S.*?\S)\1/g, '$2') .replace(/([\*_]{1,3})(\S.*?\S)\1/g, '$2')
.replace(/(`{3,})(.*?)\1/gm, '$2') .replace(/(`{3,})(.*?)\1/gm, '$2')
.replace(/^-{3,}\s*$/g, '') .replace(/^-{3,}\s*$/g, '')

View File

@@ -0,0 +1,9 @@
/**
* Varibales for note detail space.
*/
// Margin on the left side and the right side for NoteDetail component.
$note-detail-left-margin = 25px
$note-detail-right-margin = 25px
$note-detail-box-shadow = 2px 0 15px -8px #b1b1b1 inset

View File

@@ -128,8 +128,8 @@ class FolderSelect extends React.Component {
} }
nextOption () { nextOption () {
let { storages } = this.props
let { optionIndex } = this.state let { optionIndex } = this.state
let { folders } = this.props
optionIndex++ optionIndex++
if (optionIndex >= folders.length) optionIndex = 0 if (optionIndex >= folders.length) optionIndex = 0
@@ -262,13 +262,11 @@ class FolderSelect extends React.Component {
: <div styleName='idle'> : <div styleName='idle'>
<div styleName='idle-label'> <div styleName='idle-label'>
<span styleName='idle-label-name' <span styleName='idle-label-name'
style={{borderColor: currentOption.folder.color}} style={{color: currentOption.folder.color}}
> >
{currentOption.folder.name} {currentOption.folder.name} /
<span styleName='idle-label-name-surfix'>in {currentOption.storage.name}</span>
</span> </span>
</div> </div>
<i styleName='idle-caret' className='fa fa-fw fa-caret-down'/>
</div> </div>
} }

View File

@@ -7,29 +7,28 @@
transition 0.15s transition 0.15s
user-select none user-select none
&:hover &:hover
background-color white background-color $ui-button--hover-backgroundColor
border-color $ui-borderColor
.root--search, .root--focus .root--search, .root--focus
@extend .root @extend .root
background-color white background-color $ui-noteDetail-backgroundColor = #F4F4F4
border-color $ui-input--focus-borderColor border-color $ui-input--focus-borderColor
width 100px
&:hover &:hover
background-color white
border-color $ui-input--focus-borderColor border-color $ui-input--focus-borderColor
.idle .idle
position relative position relative
cursor pointer cursor pointer
.idle-label .idle-label
absolute left top
padding 0 0 0 5px
right 20px right 20px
overflow ellipsis overflow ellipsis
.idle-label-name .idle-label-name
border-left solid 4px transparent font-size 16px
padding 2px 5px padding 2px
.idle-label-name-surfix .idle-label-name-surfix
font-size 10px font-size 10px
color $ui-inactive-text-color color $ui-inactive-text-color
@@ -60,9 +59,9 @@
max-height 450px max-height 450px
overflow auto overflow auto
z-index 200 z-index 200
border $ui-border
background-color white background-color white
border-radius 2px border-radius 2px
box-shadow 2px 2px 10px gray
.search-optionList-item .search-optionList-item
height 34px height 34px
@@ -115,8 +114,8 @@ body[data-theme="dark"]
.search-optionList .search-optionList
color white color white
border-color $ui-dark-borderColor
background-color $ui-dark-button--hover-backgroundColor background-color $ui-dark-button--hover-backgroundColor
box-shadow 2px 2px 10px black
.search-optionList-item .search-optionList-item
&:hover &:hover

View File

@@ -0,0 +1,27 @@
/**
* @fileoverview Component for show updated date of the detail.
*/
import React, { PropTypes } from 'react'
import { getLastUpdated } from 'browser/lib/date-formatter'
import CSSModules from 'browser/lib/CSSModules'
import styles from './LastUpdatedString.styl'
const LastUpdatedString = ({ date }) => {
let text = ''
try {
text = `Last updated at ${getLastUpdated(date)}`
} catch (e) {
text = ''
}
return (
<p styleName='info-right-date'>{text}</p>
)
}
LastUpdatedString.propTypes = {
date: PropTypes.string
}
export default CSSModules(LastUpdatedString, styles)

View File

@@ -0,0 +1,10 @@
.info-right-date
display inline
line-height 24px
padding-right 25px
font-size 11px
color $ui-button-color
body[data-theme="dark"]
.info-right-date
color $ui-dark-button-color

View File

@@ -166,20 +166,6 @@ class MarkdownNoteDetail extends React.Component {
} }
handleShareButtonClick (e) {
let menu = new Menu()
menu.append(new MenuItem({
label: 'Export as a File',
click: (e) => this.handlePreferencesButtonClick(e)
}))
menu.append(new MenuItem({
label: 'Export to Web',
disabled: true,
click: (e) => this.handlePreferencesButtonClick(e)
}))
menu.popup(remote.getCurrentWindow())
}
handleContextButtonClick (e) { handleContextButtonClick (e) {
let menu = new Menu() let menu = new Menu()
menu.append(new MenuItem({ menu.append(new MenuItem({
@@ -229,6 +215,10 @@ class MarkdownNoteDetail extends React.Component {
> >
<div styleName='info'> <div styleName='info'>
<div styleName='info-left'> <div styleName='info-left'>
<StarButton styleName='info-left-button'
onClick={(e) => this.handleStarButtonClick(e)}
isActive={note.isStarred}
/>
<div styleName='info-left-top'> <div styleName='info-left-top'>
<FolderSelect styleName='info-left-top-folderSelect' <FolderSelect styleName='info-left-top-folderSelect'
value={this.state.note.storage + '-' + this.state.note.folder} value={this.state.note.storage + '-' + this.state.note.folder}
@@ -237,36 +227,18 @@ class MarkdownNoteDetail extends React.Component {
onChange={(e) => this.handleFolderChange(e)} onChange={(e) => this.handleFolderChange(e)}
/> />
</div> </div>
<div styleName='info-left-bottom'>
<TagSelect <TagSelect
styleName='info-left-bottom-tagSelect' ref='tags'
ref='tags' value={this.state.note.tags}
value={this.state.note.tags} onChange={(e) => this.handleChange(e)}
onChange={(e) => this.handleChange(e)} />
/>
</div>
</div> </div>
<div styleName='info-right'> <div styleName='info-right'>
<StarButton styleName='info-right-button'
onClick={(e) => this.handleStarButtonClick(e)}
isActive={note.isStarred}
/>
<button styleName='info-right-button'
onClick={(e) => this.handleShareButtonClick(e)}
disabled
>
<i className='fa fa-share-alt fa-fw' />
<span styleName='info-right-button-tooltip'
style={{right: 20}}
>Share Note</span>
</button>
<button styleName='info-right-button' <button styleName='info-right-button'
onClick={(e) => this.handleContextButtonClick(e)} onClick={(e) => this.handleContextButtonClick(e)}
> >
<i className='fa fa-ellipsis-v' /> <i className='fa fa-ellipsis-v' />
<span styleName='info-right-button-tooltip'
style={{right: 5}}
>More Options</span>
</button> </button>
</div> </div>
</div> </div>
@@ -284,6 +256,7 @@ class MarkdownNoteDetail extends React.Component {
<StatusBar <StatusBar
{..._.pick(this.props, ['config', 'location', 'dispatch'])} {..._.pick(this.props, ['config', 'location', 'dispatch'])}
date={note.updatedAt}
/> />
</div> </div>
) )

View File

@@ -1,68 +1,19 @@
$info-height = 75px @import('NoteDetailInfo')
@import('DetailVars')
.root .root
absolute top right bottom absolute top right bottom
border-width 0 0 1px border-width 0 0 1px
border-style solid border-style solid
border-color $ui-borderColor border-color $ui-borderColor
background-color $ui-noteDetail-backgroundColor
.info box-shadow $note-detail-box-shadow
absolute top left right
height $info-height
border-bottom $ui-border
background-color $ui-backgroundColor
.info-left
float left
padding 0 5px
.info-left-top
height 40px
line-height 40px
.info-left-top-folderSelect
display inline-block
height 34px
width 200px
vertical-align middle
.info-left-bottom
height 30px
.info-left-bottom-tagSelect
height 30px
line-height 30px
.info-right
float right
.info-right-button
width 34px
height 34px
border-radius 17px
navButtonColor()
border $ui-border
font-size 14px
margin 8px 2px
padding 0
&:active
border-color $ui-button--focus-borderColor
&:hover .info-right-button-tooltip
opacity 1
&:focus
border-color $ui-button--focus-borderColor
.info-right-button-tooltip
tooltip()
position fixed
top 45px
padding 5px
opacity 0
border-radius 2px
.body .body
absolute left right absolute left right
top $info-height left $note-detail-left-margin
right $note-detail-right-margin
top $info-height + $info-margin-under-border
bottom $statusBar-height bottom $statusBar-height
.body-noteEditor .body-noteEditor
@@ -71,32 +22,5 @@ $info-height = 75px
body[data-theme="dark"] body[data-theme="dark"]
.root .root
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
background-color $ui-dark-noteDetail-backgroundColor
.info box-shadow none
border-color $ui-dark-borderColor
background-color $ui-dark-backgroundColor
.info-delete
color $ui-dark-text-color
.info-delete-confirmButton
colorDarkDangerButton()
color $ui-dark-text-color
.info-delete-cancelButton
colorDarkDefaultButton()
border-color $ui-dark-borderColor
color $ui-dark-text-color
.info-right-button
navDarkButtonColor()
border-color $ui-dark-borderColor
&:active
border-color $ui-dark-button--focus-borderColor
&:hover .info-right-button-tooltip
opacity 1
&:focus
border-color $ui-button--focus-borderColor
.info-right-button-tooltip
darkTooltip()

View File

@@ -0,0 +1,98 @@
@import('DetailVars')
$info-height = 60px
$info-margin-under-border = 27px
.info
absolute top left right
left $note-detail-left-margin
right $note-detail-right-margin
height $info-height
border-bottom $ui-border
background-color $ui-noteDetail-backgroundColor
.info-left
float left
padding 0 5px
margin 0px 2px
.info-left-top
display inline-block
height $info-height
line-height $info-height
.info-left-top-folderSelect
display inline-block
padding 0 3px
height 34px
line-height 34px
vertical-align middle
border-radius 3px
.info-left-button
width 34px
height 34px
navButtonColor()
color $ui-favorite-star-button-color
font-size 14px
margin 13px 2px
padding 0
border-radius 17px
&:hover .info-right-button-tooltip
opacity 1
&:focus
border-color $ui-favorite-star-button-color
&:active, &:active:hover
background-color $ui-favorite-star-button-color
color $ui-button--active-color
.info-right
position absolute
right 0
top 0
background $ui-noteDetail-backgroundColor
bottom 1px
padding-left 30px
.info-right-button
width 34px
height 34px
border-radius 17px
font-size 14px
margin 13px 7px
padding 0
border none
color $ui-button-color
background-color transparent
&:hover
opacity 1
background-color $ui-button--hover-backgroundColor
body[data-theme="dark"]
.info
border-color $ui-dark-borderColor
background-color $ui-dark-noteDetail-backgroundColor
.info-delete
color $ui-dark-text-color
.info-delete-confirmButton
colorDarkDangerButton()
color $ui-dark-text-color
.info-delete-cancelButton
colorDarkDefaultButton()
border-color $ui-dark-borderColor
color $ui-dark-text-color
.info-right
background-color $ui-dark-noteDetail-backgroundColor
.info-right-button
navDarkButtonColor()
border-color $ui-dark-borderColor
&:active
border-color $ui-dark-button--focus-borderColor
&:focus
border-color $ui-button--focus-borderColor

View File

@@ -10,10 +10,11 @@ import dataApi from 'browser/main/lib/dataApi'
import { hashHistory } from 'react-router' import { hashHistory } from 'react-router'
import ee from 'browser/main/lib/eventEmitter' import ee from 'browser/main/lib/eventEmitter'
import CodeMirror from 'codemirror' import CodeMirror from 'codemirror'
import SnippetTab from './SnippetTab' import SnippetTab from 'browser/components/SnippetTab'
import StatusBar from '../StatusBar' import StatusBar from '../StatusBar'
import context from 'browser/lib/context' import context from 'browser/lib/context'
import ConfigManager from 'browser/main/lib/ConfigManager' import ConfigManager from 'browser/main/lib/ConfigManager'
import _ from 'lodash'
function pass (name) { function pass (name) {
switch (name) { switch (name) {
@@ -188,21 +189,6 @@ class SnippetNoteDetail extends React.Component {
} }
handleShareButtonClick (e) {
let menu = new Menu()
menu.append(new MenuItem({
label: 'Export as a File',
disabled: true,
click: (e) => this.handlePreferencesButtonClick(e)
}))
menu.append(new MenuItem({
label: 'Export to Web',
disabled: true,
click: (e) => this.handlePreferencesButtonClick(e)
}))
menu.popup(remote.getCurrentWindow())
}
handleContextButtonClick (e) { handleContextButtonClick (e) {
context.popup([{ context.popup([{
label: 'Delete', label: 'Delete',
@@ -507,7 +493,7 @@ class SnippetNoteDetail extends React.Component {
key={index} key={index}
style={{zIndex: isActive ? 5 : 4}} style={{zIndex: isActive ? 5 : 4}}
> >
{snippet.mode === 'markdown' {snippet.mode === 'Markdown' || snippet.mode === 'GitHub Flavored Markdown'
? <MarkdownEditor styleName='tabView-content' ? <MarkdownEditor styleName='tabView-content'
value={snippet.content} value={snippet.content}
config={config} config={config}
@@ -523,6 +509,7 @@ class SnippetNoteDetail extends React.Component {
fontSize={editorFontSize} fontSize={editorFontSize}
indentType={config.editor.indentType} indentType={config.editor.indentType}
indentSize={editorIndentSize} indentSize={editorIndentSize}
keyMap={config.editor.keyMap}
onChange={(e) => this.handleCodeChange(index)(e)} onChange={(e) => this.handleCodeChange(index)(e)}
ref={'code-' + index} ref={'code-' + index}
/> />
@@ -538,6 +525,10 @@ class SnippetNoteDetail extends React.Component {
> >
<div styleName='info'> <div styleName='info'>
<div styleName='info-left'> <div styleName='info-left'>
<StarButton styleName='info-left-button'
onClick={(e) => this.handleStarButtonClick(e)}
isActive={note.isStarred}
/>
<div styleName='info-left-top'> <div styleName='info-left-top'>
<FolderSelect styleName='info-left-top-folderSelect' <FolderSelect styleName='info-left-top-folderSelect'
value={this.state.note.storage + '-' + this.state.note.folder} value={this.state.note.storage + '-' + this.state.note.folder}
@@ -546,36 +537,18 @@ class SnippetNoteDetail extends React.Component {
onChange={(e) => this.handleFolderChange(e)} onChange={(e) => this.handleFolderChange(e)}
/> />
</div> </div>
<div styleName='info-left-bottom'>
<TagSelect <TagSelect
styleName='info-left-bottom-tagSelect' ref='tags'
ref='tags' value={this.state.note.tags}
value={this.state.note.tags} onChange={(e) => this.handleChange(e)}
onChange={(e) => this.handleChange(e)} />
/>
</div>
</div> </div>
<div styleName='info-right'> <div styleName='info-right'>
<StarButton styleName='info-right-button'
onClick={(e) => this.handleStarButtonClick(e)}
isActive={note.isStarred}
/>
<button styleName='info-right-button'
onClick={(e) => this.handleShareButtonClick(e)}
disabled
>
<i className='fa fa-share-alt fa-fw'/>
<span styleName='info-right-button-tooltip'
style={{right: 20}}
>Share Note</span>
</button>
<button styleName='info-right-button' <button styleName='info-right-button'
onClick={(e) => this.handleContextButtonClick(e)} onClick={(e) => this.handleContextButtonClick(e)}
> >
<i className='fa fa-ellipsis-v'/> <i className='fa fa-ellipsis-v' />
<span styleName='info-right-button-tooltip'
style={{right: 5}}
>More Options</span>
</button> </button>
</div> </div>
</div> </div>
@@ -600,7 +573,7 @@ class SnippetNoteDetail extends React.Component {
<button styleName='plusButton' <button styleName='plusButton'
onClick={(e) => this.handleTabPlusButtonClick(e)} onClick={(e) => this.handleTabPlusButtonClick(e)}
> >
<i className='fa fa-plus'/> <i className='fa fa-plus' />
</button> </button>
</div> </div>
{viewList} {viewList}
@@ -614,24 +587,25 @@ class SnippetNoteDetail extends React.Component {
? 'Select Syntax...' ? 'Select Syntax...'
: this.state.note.snippets[this.state.snippetIndex].mode : this.state.note.snippets[this.state.snippetIndex].mode
}&nbsp; }&nbsp;
<i className='fa fa-caret-down'/> <i className='fa fa-caret-down' />
</button> </button>
<button <button
onClick={(e) => this.handleIndentTypeButtonClick(e)} onClick={(e) => this.handleIndentTypeButtonClick(e)}
> >
Indent: {config.editor.indentType}&nbsp; Indent: {config.editor.indentType}&nbsp;
<i className='fa fa-caret-down'/> <i className='fa fa-caret-down' />
</button> </button>
<button <button
onClick={(e) => this.handleIndentSizeButtonClick(e)} onClick={(e) => this.handleIndentSizeButtonClick(e)}
> >
size: {config.editor.indentSize}&nbsp; size: {config.editor.indentSize}&nbsp;
<i className='fa fa-caret-down'/> <i className='fa fa-caret-down' />
</button> </button>
</div> </div>
<StatusBar <StatusBar
{..._.pick(this.props, ['config', 'location', 'dispatch'])} {..._.pick(this.props, ['config', 'location', 'dispatch'])}
date={note.updatedAt}
/> />
</div> </div>
) )

View File

@@ -1,72 +1,25 @@
$info-height = 75px @import('NoteDetailInfo')
@import('DetailVars')
.root .root
absolute top bottom right absolute top bottom right
border-width 0 0 1px border-width 0 0 1px
border-style solid border-style solid
border-color $ui-borderColor border-color $ui-borderColor
background-color $ui-noteDetail-backgroundColor
.info box-shadow $note-detail-box-shadow
absolute top left right
height $info-height
border-bottom $ui-border
background-color $ui-backgroundColor
.info-left
float left
padding 0 5px
.info-left-top
height 40px
line-height 40px
.info-left-top-folderSelect
display inline-block
height 34px
width 200px
vertical-align middle
.info-left-bottom
height 30px
.info-left-bottom-tagSelect
height 30px
line-height 30px
.info-right
float right
.info-right-button
width 34px
height 34px
border-radius 17px
navButtonColor()
border $ui-border
font-size 14px
margin 8px 2px
padding 0
&:active
border-color $ui-button--focus-borderColor
&:hover .info-right-button-tooltip
opacity 1
&:focus
border-color $ui-button--focus-borderColor
.info-right-button-tooltip
tooltip()
position fixed
top 45px
padding 5px
opacity 0
.body .body
absolute left right absolute left right
top $info-height left $note-detail-left-margin
right $note-detail-right-margin
top $info-height + $info-margin-under-border
bottom $statusBar-height bottom $statusBar-height
background-color $ui-noteDetail-backgroundColor
.body .description .body .description
absolute top left right absolute top left right
height 80px height 80px
border-bottom $ui-border
.body .description textarea .body .description textarea
display block display block
@@ -76,20 +29,19 @@ $info-height = 75px
border none border none
padding 10px padding 10px
line-height 1.6 line-height 1.6
background-color $ui-noteDetail-backgroundColor
.tabList .tabList
absolute left right absolute left right
top 80px top 80px
height 30px height 30px
border-bottom $ui-border
display flex display flex
background-color $ui-backgroundColor background-color $ui-noteDetail-backgroundColor
.tabList .list .tabList .list
flex 1 flex 1
display flex display flex
overflow hidden overflow hidden
border-right $ui-border
.tabList .plusButton .tabList .plusButton
navButtonColor() navButtonColor()
@@ -97,13 +49,14 @@ $info-height = 75px
.tabView .tabView
absolute left right bottom absolute left right bottom
top 110px top 130px
.tabView-content .tabView-content
absolute top left right bottom absolute top left right bottom
.override .override
absolute bottom left absolute bottom left
left 60px
height 23px height 23px
z-index 1 z-index 1
button button
@@ -118,50 +71,25 @@ $info-height = 75px
body[data-theme="dark"] body[data-theme="dark"]
.root .root
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
background-color $ui-dark-noteDetail-backgroundColor
box-shadow none
.info .body
border-bottom-color $ui-dark-borderColor background-color $ui-dark-noteDetail-backgroundColor
background-color $ui-dark-backgroundColor
.info-delete
color $ui-dark-text-color
.info-delete-confirmButton
colorDarkDangerButton()
color $ui-dark-text-color
.info-delete-cancelButton
colorDarkDefaultButton()
border-color $ui-dark-borderColor
color $ui-dark-text-color
.info-right-button
navDarkButtonColor()
border-color $ui-dark-borderColor
&:active
border-color $ui-dark-button--focus-borderColor
&:hover .info-right-button-tooltip
opacity 1
&:focus
border-color $ui-button--focus-borderColor
.info-right-button-tooltip
darkTooltip()
.body .description
border-bottom-color $ui-dark-borderColor
.body .description textarea .body .description textarea
background-color $ui-dark-button--hover-backgroundColor background-color $ui-dark-noteDetail-backgroundColor
color white color white
.tabList .tabList
background-color $ui-button--active-backgroundColor background-color $ui-button--active-backgroundColor
border-bottom-color $ui-dark-borderColor background-color $ui-dark-noteDetail-backgroundColor
background-color $ui-dark-backgroundColor
.tabList .list .tabList .list
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
.tabList .plusButton .tabList .plusButton
navDarkButtonColor() navDarkButtonColor()
.override
button
border-color $ui-dark-borderColor

View File

@@ -53,7 +53,6 @@ class StarButton extends React.Component {
: 'fa fa-star-o' : 'fa fa-star-o'
} }
/> />
<span styleName='tooltip'>Star Note</span>
</button> </button>
) )
} }

View File

@@ -1,5 +1,6 @@
.root .root
position relative left 7px
top 0
padding 0 padding 0
&:hover &:hover
.icon .icon
@@ -9,19 +10,11 @@
.root--active .root--active
@extend .root @extend .root
color $brand-color color $ui-favorite-star-button-color
&:hover &:hover
color $brand-color !important color $ui-favorite-star-button-color
.icon .icon
transform rotate(-72deg) transform rotate(-72deg)
.icon .icon
transition transform 0.15s transition transform 0.15s
.tooltip
tooltip()
position fixed
top 45px
right 65px
padding 5px
opacity 0
border-radius 2px

View File

@@ -107,12 +107,12 @@ class TagSelect extends React.Component {
<span styleName='tag' <span styleName='tag'
key={tag} key={tag}
> >
<span styleName='tag-label'>{tag}</span>
<button styleName='tag-removeButton' <button styleName='tag-removeButton'
onClick={(e) => this.handleTagRemoveButtonClick(tag)(e)} onClick={(e) => this.handleTagRemoveButtonClick(tag)(e)}
> >
<i className='fa fa-times fa-fw'/> <i className='fa fa-times fa-fw tag-removeButton-icon' />
</button> </button>
<span styleName='tag-label'>{tag}</span>
</span> </span>
) )
}) })
@@ -125,10 +125,7 @@ class TagSelect extends React.Component {
} }
styleName='root' styleName='root'
> >
<i styleName='icon' {tagList}
className='fa fa-tags'
/>
{tagList}
<input styleName='newTag' <input styleName='newTag'
ref='newTag' ref='newTag'
value={this.state.newTag} value={this.state.newTag}
@@ -136,7 +133,6 @@ class TagSelect extends React.Component {
onChange={(e) => this.handleNewTagInputChange(e)} onChange={(e) => this.handleNewTagInputChange(e)}
onKeyDown={(e) => this.handleNewTagInputKeyDown(e)} onKeyDown={(e) => this.handleNewTagInputKeyDown(e)}
/> />
</div> </div>
) )
} }

View File

@@ -1,46 +1,47 @@
.root .root
position relative
user-select none
.icon
display inline-block display inline-block
width 30px top 19px
user-select none
vertical-align middle vertical-align middle
text-align center width 300px
color $ui-button-color overflow-x scroll
white-space nowrap
.root::-webkit-scrollbar
display none
.tag .tag
display inline-block display inline-block
margin 0 2px margin 0 2px
padding-left 10px
vertical-align middle vertical-align middle
height 20px height 20px
background-color white background-color $ui-tag-backgroundColor
border-radius 3px border-radius 20px
overflow hidden overflow hidden
clearfix() clearfix()
.tag-removeButton .tag-removeButton
float left float right
height 20px height 20px
width 18px width 18px
margin 0 margin 0
padding 0 padding 0
border-style solid border-style solid
border-color $ui-button--focus-borderColor border-width 0
border-width 0 0 0 3px border-radius 20px
line-height 18px line-height 18px
background-color transparent background-color transparent
color $ui-button-color color $ui-button-color
&:hover
background-color $ui-button--hover-backgroundColor .tag-removeButton-icon
&:active, &:active:hover width 5px
color $ui-button--active-color padding-right 4px
background-color $ui-button--active-backgroundColor
border-color $ui-button--focus-borderColor
&:focus
border-color $ui-button--focus-borderColor
.tag-label .tag-label
font-size 12px
font-weight bold
color: #FFFFFF
float left float left
height 20px height 20px
line-height 20px line-height 20px
@@ -62,12 +63,27 @@
&:disabled &:disabled
background-color $ui-input--disabled-backgroundColor = #DDD background-color $ui-input--disabled-backgroundColor = #DDD
.add-tag-button
display inline
margin-left 5px
width 20px
height 20px
border none
border-radius 20px
padding 0
color #FFFFFF
&:hover
background-color rgba(0, 0, 0, 0.3)
&:active, &:active:hover
background-color rgba(0, 0, 0, 0.5)
color $ui-button--active-color
body[data-theme="dark"] body[data-theme="dark"]
.icon .icon
color $ui-dark-button-color color $ui-dark-button-color
.tag .tag
background-color $ui-dark-button--hover-backgroundColor background-color $ui-dark-tag-backgroundColor
.tag-removeButton .tag-removeButton
border-color $ui-button--focus-borderColor border-color $ui-button--focus-borderColor
@@ -85,3 +101,10 @@ body[data-theme="dark"]
border-color $ui-input--focus-borderColor = #369DCD border-color $ui-input--focus-borderColor = #369DCD
&:disabled &:disabled
background-color $ui-input--disabled-backgroundColor = #DDD background-color $ui-input--disabled-backgroundColor = #DDD
.add-tag-button
&:hover
background-color rgba(255, 255, 255, 0.3)
&:active, &:active:hover
background-color rgba(255, 255, 255, 0.5)
color $ui-button--active-color

View File

@@ -26,7 +26,7 @@ class Main extends React.Component {
this.state = { this.state = {
isRightSliderFocused: false, isRightSliderFocused: false,
listWidth: config.listWidth, listWidth: config.listWidth,
navWidth: config.listWidth, navWidth: config.navWidth,
isLeftSliderFocused: false isLeftSliderFocused: false
} }
} }
@@ -85,6 +85,7 @@ class Main extends React.Component {
} }
handleMouseUp (e) { handleMouseUp (e) {
// Change width of NoteList component.
if (this.state.isRightSliderFocused) { if (this.state.isRightSliderFocused) {
this.setState({ this.setState({
isRightSliderFocused: false isRightSliderFocused: false
@@ -99,6 +100,8 @@ class Main extends React.Component {
}) })
}) })
} }
// Change width of SideNav component.
if (this.state.isLeftSliderFocused) { if (this.state.isLeftSliderFocused) {
this.setState({ this.setState({
isLeftSliderFocused: false isLeftSliderFocused: false
@@ -106,10 +109,10 @@ class Main extends React.Component {
let { dispatch } = this.props let { dispatch } = this.props
let navWidth = this.state.navWidth let navWidth = this.state.navWidth
// TODO: ConfigManager should dispatch itself. // TODO: ConfigManager should dispatch itself.
ConfigManager.set({listWidth: navWidth}) ConfigManager.set({ navWidth })
dispatch({ dispatch({
type: 'SET_NAV_WIDTH', type: 'SET_NAV_WIDTH',
listWidth: navWidth navWidth
}) })
}) })
} }
@@ -162,11 +165,11 @@ class Main extends React.Component {
/> />
{!config.isSideNavFolded && {!config.isSideNavFolded &&
<div styleName={this.state.isLeftSliderFocused ? 'slider--active' : 'slider'} <div styleName={this.state.isLeftSliderFocused ? 'slider--active' : 'slider'}
style={{left: this.state.navWidth - 1}} style={{left: this.state.navWidth}}
onMouseDown={(e) => this.handleLeftSlideMouseDown(e)} onMouseDown={(e) => this.handleLeftSlideMouseDown(e)}
draggable='false' draggable='false'
> >
<div styleName='slider-hitbox'/> <div styleName='slider-hitbox' />
</div> </div>
} }
<div styleName={config.isSideNavFolded ? 'body--expanded' : 'body'} <div styleName={config.isSideNavFolded ? 'body--expanded' : 'body'}
@@ -191,15 +194,15 @@ class Main extends React.Component {
'location' 'location'
])} ])}
/> />
<div styleName={this.state.isRightSliderFocused ? 'slider--active' : 'slider'} <div styleName={this.state.isRightSliderFocused ? 'slider-right--active' : 'slider-right'}
style={{left: this.state.listWidth}} style={{left: this.state.listWidth - 1}}
onMouseDown={(e) => this.handleRightSlideMouseDown(e)} onMouseDown={(e) => this.handleRightSlideMouseDown(e)}
draggable='false' draggable='false'
> >
<div styleName='slider-hitbox' /> <div styleName='slider-hitbox' />
</div> </div>
<Detail <Detail
style={{left: this.state.listWidth + 1}} style={{left: this.state.listWidth}}
{..._.pick(this.props, [ {..._.pick(this.props, [
'dispatch', 'dispatch',
'data', 'data',

View File

@@ -11,15 +11,18 @@
.slider .slider
absolute top bottom absolute top bottom
top -2px
width 0
.slider-right
@extend .slider
width 1px width 1px
background-color $ui-borderColor
border-width 0
border-style solid
border-color $ui-borderColor
.slider--active .slider--active
@extend .slider @extend .slider
background-color $ui-button--active-backgroundColor
.slider-right--active
@extend .slider-right
.slider-hitbox .slider-hitbox
absolute top bottom left right absolute top bottom left right
@@ -33,9 +36,6 @@ body[data-theme="dark"]
.root .root
absolute top left bottom right absolute top left bottom right
.slider .slider-right
background-color $ui-dark-borderColor .slider-right--active
border-color $ui-dark-borderColor box-shadow none
.slider--active
background-color $ui-button--active-backgroundColor

View File

@@ -1,168 +0,0 @@
import React, { PropTypes } from 'react'
import ReactDOM from 'react-dom'
import api from 'browser/lib/api'
import clientKey from 'browser/lib/clientKey'
import activityRecord from 'browser/lib/activityRecord'
const clipboard = require('electron').clipboard
function notify (...args) {
return new window.Notification(...args)
}
function getDefault () {
return {
openDropdown: false,
isSharing: false,
// Fetched url
url: null,
// for tooltip Copy -> Copied!
copied: false,
failed: false
}
}
export default class ShareButton extends React.Component {
constructor (props) {
super(props)
this.state = getDefault()
}
componentWillReceiveProps (nextProps) {
this.setState(getDefault())
}
componentDidMount () {
this.dropdownInterceptor = e => {
this.dropdownClicked = true
}
ReactDOM.findDOMNode(this.refs.dropdown).addEventListener('click', this.dropdownInterceptor)
this.shareViaPublicURLHandler = e => {
this.handleShareViaPublicURLClick(e)
}
}
componentWillUnmount () {
document.removeEventListener('click', this.dropdownHandler)
ReactDOM.findDOMNode(this.refs.dropdown).removeEventListener('click', this.dropdownInterceptor)
}
handleOpenButtonClick (e) {
this.openDropdown()
if (this.dropdownHandler == null) {
this.dropdownHandler = e => {
if (!this.dropdownClicked) {
this.closeDropdown()
} else {
this.dropdownClicked = false
}
}
}
document.removeEventListener('click', this.dropdownHandler)
document.addEventListener('click', this.dropdownHandler)
}
openDropdown () {
this.setState({openDropdown: true})
}
closeDropdown () {
document.removeEventListener('click', this.dropdownHandler)
this.setState({openDropdown: false})
}
handleClipboardButtonClick (e) {
activityRecord.emit('MAIN_DETAIL_COPY')
clipboard.writeText(this.props.article.content)
notify('Saved to Clipboard!', {
body: 'Paste it wherever you want!'
})
this.setState({openDropdown: false})
}
handleShareViaPublicURLClick (e) {
let { user } = this.props
let input = Object.assign({}, this.props.article, {
clientKey: clientKey.get(),
writerName: user.name
})
this.setState({
isSharing: true,
failed: false
}, () => {
api.shareViaPublicURL(input)
.then(res => {
let url = res.body.url
this.setState({url: url, isSharing: false})
activityRecord.emit('ARTICLE_SHARE')
})
.catch(err => {
console.log(err)
this.setState({isSharing: false, failed: true})
})
})
}
handleCopyURLClick () {
clipboard.writeText(this.state.url)
this.setState({copied: true})
}
// Restore copy url tooltip
handleCopyURLMouseLeave () {
this.setState({copied: false})
}
render () {
let hasPublicURL = this.state.url != null
return (
<div className='ShareButton'>
<button ref='openButton' onClick={e => this.handleOpenButtonClick(e)} className='ShareButton-open-button'>
<i className='fa fa-fw fa-share-alt'/>
{
this.state.openDropdown ? null : (
<span className='tooltip'>Share</span>
)
}
</button>
<div ref='dropdown' className={'ShareButton-dropdown' + (this.state.openDropdown ? '' : ' hide')}>
{
!hasPublicURL ? (
<button
onClick={e => this.shareViaPublicURLHandler(e)}
ref='sharePublicURL'
disabled={this.state.isSharing}>
<i className='fa fa-fw fa-external-link'/> {this.state.failed ? 'Failed : Click to Try again' : !this.state.isSharing ? 'Share via public URL' : 'Sharing...'}
</button>
) : (
<div className='ShareButton-url'>
<input className='ShareButton-url-input' value={this.state.url} readOnly/>
<button
onClick={e => this.handleCopyURLClick(e)}
className='ShareButton-url-button'
onMouseLeave={e => this.handleCopyURLMouseLeave(e)}
>
<i className='fa fa-fw fa-clipboard'/>
<div className='ShareButton-url-button-tooltip'>{this.state.copied ? 'Copied!' : 'Copy URL'}</div>
</button>
<div className='ShareButton-url-alert'>This url is valid for 7 days.</div>
</div>
)
}
<button onClick={e => this.handleClipboardButtonClick(e)}>
<i className='fa fa-fw fa-clipboard'/>&nbsp;Copy to clipboard
</button>
</div>
</div>
)
}
}
ShareButton.propTypes = {
article: PropTypes.shape({
publicURL: PropTypes.string,
content: PropTypes.string
}),
user: PropTypes.shape({
name: PropTypes.string
})
}

View File

@@ -1,25 +1,28 @@
$control-height = 30px
.root .root
absolute left bottom absolute left bottom
border-top $ui-border
top $topBar-height - 1 top $topBar-height - 1
background-color $ui-noteList-backgroundColor
.control .control
absolute top left right absolute top left right
user-select none user-select none
height 25px height $control-height
font-size 10px font-size 12px
border-bottom $ui-border
line-height 25px line-height 25px
display flex display flex
background-color $ui-backgroundColor background-color $ui-noteList-backgroundColor
color $ui-inactive-text-color color $ui-inactive-text-color
.control-sortBy .control-sortBy
flex 1 flex 1
padding-left 5px padding-left 25px
.control-sortBy-select .control-sortBy-select
margin-left 5px margin-left 0
font-size 12px
color $ui-inactive-text-color
padding 0 padding 0
border none border none
background-color transparent background-color transparent
@@ -36,8 +39,6 @@
color $ui-active-color color $ui-active-color
&:hover &:hover
color $ui-text-color color $ui-text-color
.control-button-tooltip
opacity 1
.control-button--active .control-button--active
@extend .control-button @extend .control-button
@@ -45,178 +46,22 @@
&:hover &:hover
color $ui-active-color color $ui-active-color
.control-button-tooltip
tooltip()
position absolute
top 20px
right 5px
padding 5px
opacity 0
white-space nowrap
border-radius 2px
z-index 1
.list .list
absolute left right bottom absolute left right bottom
top 24px top $control-height
overflow auto overflow auto
.item
position relative
border-bottom $ui-border
padding 2px 5px
user-select none
cursor pointer
transition background-color 0.15s
&:hover
background-color alpha($ui-active-color, 20%)
&:active
background-color $ui-active-color
color white
.item-title
.item-title-empty
.item-title-icon
.item-bottom-tagIcon
.item-bottom-tagList-empty
.item-bottom-time
color white
.item-bottom-tagList-item
background-color transparent
color white
.item--active
@extend .item
background-color $ui-active-color
color white
.item-title
.item-title-empty
.item-title-icon
.item-bottom-tagIcon
.item-bottom-tagList-empty
.item-bottom-time
color white
.item-bottom-tagList-item
background-color transparent
color white
&:hover
background-color $ui-active-color
.item-border
absolute top bottom left right
border-style solid
border-width 2px
border-color transparent
transition 0.15s
.item-title
height 24px
box-sizing border-box
line-height 24px
padding 0
overflow ellipsis
color $ui-text-color
.item-title-icon
font-size 12px
color $ui-inactive-text-color
padding-right 3px
.item-title-empty
font-weight normal
color $ui-inactive-text-color
.item-bottom
margin-top 2px
height 20px
font-size 12px
line-height 20px
overflow ellipsis
display flex
.item-bottom-tagIcon
vertical-align middle
color $ui-button-color
height 20px
line-height 20px
.item-bottom-tagList
flex 1
overflow ellipsis
line-height 20px
.item-bottom-tagList-item
margin 0 4px
padding 0 4px
height 20px
box-sizing border-box
border-radius 3px
vertical-align middle
border-style solid
border-color $ui-button--focus-borderColor
border-width 0 0 0 3px
background-color $ui-backgroundColor
color $ui-text-color
.item-bottom-tagList-empty
color $ui-inactive-text-color
vertical-align middle
font-size 10px
margin-left 5px
.item-bottom-time
color $ui-inactive-text-color
margin-left 5px
font-size 10px
body[data-theme="dark"] body[data-theme="dark"]
.root .root
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
background-color $ui-dark-backgroundColor background-color $ui-dark-noteList-backgroundColor
.item
border-color $ui-dark-borderColor
&:hover
background-color alpha($ui-active-color, 20%)
.item--active
@extend .item
border-color $ui-dark-borderColor
.item-title
color white
.item-bottom-tagList-item
background-color transparent
color white
.item-bottom-tagList-empty
color white
&:hover
background-color $ui-active-color
.item-title
color $ui-dark-text-color
.item-title-icon
color $ui-darkinactive-text-color
.item-title-empty
color $ui-dark-inactive-text-color
.item-bottom-tagIcon
color $ui-dark-button-color
.item-bottom-tagList-item
border-color $ui-dark-button--focus-borderColor
background-color $ui-dark-button--hover-backgroundColor
color $ui-dark-text-color
.item-bottom-tagList-empty
color $ui-inactive-text-color
vertical-align middle
.control .control
background-color $ui-dark-backgroundColor background-color $ui-dark-noteList-backgroundColor
.control
background-color $ui-dark-noteList-backgroundColor
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
.control-sortBy-select
color $ui-dark-text-color
.control-button .control-button
color $ui-dark-inactive-text-color color $ui-dark-inactive-text-color

View File

@@ -6,6 +6,8 @@ import _ from 'lodash'
import ee from 'browser/main/lib/eventEmitter' import ee from 'browser/main/lib/eventEmitter'
import dataApi from 'browser/main/lib/dataApi' import dataApi from 'browser/main/lib/dataApi'
import ConfigManager from 'browser/main/lib/ConfigManager' import ConfigManager from 'browser/main/lib/ConfigManager'
import NoteItem from 'browser/components/NoteItem'
import NoteItemSimple from 'browser/components/NoteItemSimple'
const { remote } = require('electron') const { remote } = require('electron')
const { Menu, MenuItem, dialog } = remote const { Menu, MenuItem, dialog } = remote
@@ -314,57 +316,40 @@ class NoteList extends React.Component {
.sort(sortFunc) .sort(sortFunc)
let noteList = notes let noteList = notes
.map((note) => { .map(note => {
if (note == null) return null if (note == null) {
let tagElements = _.isArray(note.tags) return null
? note.tags.map((tag) => { }
return (
<span styleName='item-bottom-tagList-item' const isDefault = config.listStyle === 'DEFAULT'
key={tag}> const isActive = location.query.key === note.storage + '-' + note.key
{tag} const dateDisplay = moment(
</span> config.sortBy === 'CREATED_AT'
) ? note.createdAt : note.updatedAt
}) ).fromNow()
: [] const key = `${note.storage}-${note.key}`
let isActive = location.query.key === note.storage + '-' + note.key
if (isDefault) {
return (
<NoteItem
isActive={isActive}
note={note}
dateDisplay={dateDisplay}
key={key}
handleNoteClick={this.handleNoteClick.bind(this)}
handleNoteContextMenu={this.handleNoteContextMenu.bind(this)}
/>
)
}
return ( return (
<div styleName={isActive <NoteItemSimple
? 'item--active' isActive={isActive}
: 'item' note={note}
} key={key}
key={note.storage + '-' + note.key} handleNoteClick={this.handleNoteClick.bind(this)}
onClick={(e) => this.handleNoteClick(e, note.storage + '-' + note.key)} handleNoteContextMenu={this.handleNoteContextMenu.bind(this)}
onContextMenu={(e) => this.handleNoteContextMenu(e, note.storage + '-' + note.key)} />
>
<div styleName='item-title'>
{note.type === 'SNIPPET_NOTE'
? <i styleName='item-title-icon' className='fa fa-fw fa-code'/>
: <i styleName='item-title-icon' className='fa fa-fw fa-file-text-o'/>
}
{note.title.trim().length > 0
? note.title
: <span styleName='item-title-empty'>Empty</span>
}
</div>
{config.listStyle === 'DEFAULT' &&
<div styleName='item-bottom'>
<i styleName='item-bottom-tagIcon'
className='fa fa-tags fa-fw'
/>
<div styleName='item-bottom-tagList'>
{tagElements.length > 0
? tagElements
: <span styleName='item-bottom-tagList-empty'>Not tagged yet</span>
}
</div>
<div styleName='item-bottom-time'>
{moment(config.sortBy === 'CREATED_AT' ? note.createdAt : note.updatedAt).fromNow()}
</div>
</div>
}
</div>
) )
}) })
@@ -391,10 +376,7 @@ class NoteList extends React.Component {
} }
onClick={(e) => this.handleListStyleButtonClick(e, 'DEFAULT')} onClick={(e) => this.handleListStyleButtonClick(e, 'DEFAULT')}
> >
<i className='fa fa-th-list'/> <i className='fa fa-th-large' />
<span styleName='control-button-tooltip'>
Default Size
</span>
</button> </button>
<button styleName={config.listStyle === 'SMALL' <button styleName={config.listStyle === 'SMALL'
? 'control-button--active' ? 'control-button--active'
@@ -402,10 +384,7 @@ class NoteList extends React.Component {
} }
onClick={(e) => this.handleListStyleButtonClick(e, 'SMALL')} onClick={(e) => this.handleListStyleButtonClick(e, 'SMALL')}
> >
<i className='fa fa-list'/> <i className='fa fa-list-ul' />
<span styleName='control-button-tooltip'>
Small Size
</span>
</button> </button>
</div> </div>
<div styleName='list' <div styleName='list'

View File

@@ -1,19 +1,17 @@
.root .root
absolute top left bottom absolute top left bottom
width $sideNav-width width $sideNav-width
border-right $ui-border
background-color $ui-backgroundColor background-color $ui-backgroundColor
user-select none user-select none
color $ui-text-color color $ui-text-color
.top .top
height $topBar-height height $topBar-height
border-bottom $ui-border
.top-menu .top-menu
navButtonColor() navButtonColor()
height $topBar-height - 1 height $topBar-height - 1
padding 0 10px padding 0 15px
font-size 14px font-size 14px
width 100% width 100%
text-align left text-align left
@@ -22,32 +20,10 @@
margin-left 5px margin-left 5px
overflow ellipsis overflow ellipsis
.menu
margin 0
.menu-button
navButtonColor()
height 32px
padding 0 10px
font-size 14px
width 100%
text-align left
overflow ellipsis
.menu-button--active
@extend .menu-button
background-color $ui-button--active-backgroundColor
color $ui-button--active-color
&:hover
background-color $ui-button--active-backgroundColor
.menu-button-label
margin-left 5px
.storageList .storageList
absolute left right absolute left right
bottom 32px bottom 37px
top 120px top 160px
overflow-y auto overflow-y auto
.storageList-empty .storageList-empty
@@ -135,16 +111,6 @@ body[data-theme="dark"]
.top-menu .top-menu
navDarkButtonColor() navDarkButtonColor()
.menu-button
navDarkButtonColor()
.menu-button--active
@extend .menu-button
background-color $ui-dark-button--active-backgroundColor
color $ui-dark-button--active-color
&:hover
background-color $ui-dark-button--active-backgroundColor
.storageList-empty .storageList-empty
color $ui-dark-inactive-text-color color $ui-dark-inactive-text-color

View File

@@ -6,6 +6,7 @@ import modal from 'browser/main/lib/modal'
import CreateFolderModal from 'browser/main/modals/CreateFolderModal' import CreateFolderModal from 'browser/main/modals/CreateFolderModal'
import RenameFolderModal from 'browser/main/modals/RenameFolderModal' import RenameFolderModal from 'browser/main/modals/RenameFolderModal'
import dataApi from 'browser/main/lib/dataApi' import dataApi from 'browser/main/lib/dataApi'
import StorageItemChild from 'browser/components/StorageItem'
const { remote } = require('electron') const { remote } = require('electron')
const { Menu, MenuItem, dialog } = remote const { Menu, MenuItem, dialog } = remote
@@ -134,34 +135,24 @@ class StorageItem extends React.Component {
let { storage, location, isFolded, data } = this.props let { storage, location, isFolded, data } = this.props
let { folderNoteMap } = data let { folderNoteMap } = data
let folderList = storage.folders.map((folder) => { let folderList = storage.folders.map((folder) => {
let isActive = location.pathname.match(new RegExp('\/storages\/' + storage.key + '\/folders\/' + folder.key)) let isActive = !!(location.pathname.match(new RegExp('\/storages\/' + storage.key + '\/folders\/' + folder.key)))
let noteSet = folderNoteMap.get(storage.key + '-' + folder.key) let noteSet = folderNoteMap.get(storage.key + '-' + folder.key)
let noteCount = noteSet != null let noteCount = noteSet != null
? noteSet.size ? noteSet.size
: 0 : 0
return <button styleName={isActive return (
? 'folderList-item--active' <StorageItemChild
: 'folderList-item' key={folder.key}
} isActive={isActive}
key={folder.key} handleButtonClick={(e) => this.handleFolderButtonClick(folder.key)(e)}
onClick={(e) => this.handleFolderButtonClick(folder.key)(e)} handleContextMenu={(e) => this.handleFolderButtonContextMenu(e, folder)}
onContextMenu={(e) => this.handleFolderButtonContextMenu(e, folder)} folderName={folder.name}
> folderColor={folder.color}
<span styleName='folderList-item-name' isFolded={isFolded}
style={{borderColor: folder.color}} noteCount={noteCount}
> />
{isFolded ? folder.name.substring(0, 1) : folder.name} )
</span>
{!isFolded &&
<span styleName='folderList-item-noteCount'>{noteCount}</span>
}
{isFolded &&
<span styleName='folderList-item-tooltip'>
{folder.name}
</span>
}
</button>
}) })
let isActive = location.pathname.match(new RegExp('\/storages\/' + storage.key + '$')) let isActive = location.pathname.match(new RegExp('\/storages\/' + storage.key + '$'))
@@ -190,7 +181,7 @@ class StorageItem extends React.Component {
<button styleName='header-addFolderButton' <button styleName='header-addFolderButton'
onClick={(e) => this.handleAddFolderButtonClick(e)} onClick={(e) => this.handleAddFolderButtonClick(e)}
> >
<i className='fa fa-plus'/> <i className='fa fa-plus' />
</button> </button>
} }

View File

@@ -1,10 +1,12 @@
.root .root
width 100% width 100%
user-select none user-select none
.header .header
position relative position relative
height 26px height 26px
width 100% width 100%
margin-bottom 5px
transition 0.15s transition 0.15s
&:hover &:hover
background-color $ui-button--hover-backgroundColor background-color $ui-button--hover-backgroundColor
@@ -45,7 +47,7 @@
.header-info .header-info
display block display block
width 100% width 100%
height 26px height 30px
padding-left 25px padding-left 25px
padding-right 10px padding-right 10px
line-height 26px line-height 26px
@@ -78,64 +80,6 @@
&:active &:active
color $ui-active-color color $ui-active-color
.folderList-item
display flex
width 100%
height 26px
background-color transparent
color $ui-inactive-text-color
padding 0
margin-bottom 2px
text-align left
border none
overflow ellipsis
font-size 14px
&:first-child
margin-top 0
&:hover
background-color $ui-button--hover-backgroundColor
&:active
color $ui-button--active-color
background-color $ui-button--active-backgroundColor
.folderList-item--active
@extend .folderList-item
color $ui-button--active-color
background-color $ui-button--active-backgroundColor
&:hover
color $ui-button--active-color
background-color $ui-button--active-backgroundColor
.folderList-item-name
display block
flex 1
padding 0 10px
height 26px
line-height 26px
border-width 0 0 0 6px
border-style solid
border-color transparent
.folderList-item-noteCount
float right
line-height 26px
padding-right 5px
font-size 12px
.folderList-item-tooltip
tooltip()
position fixed
padding 0 10px
left 44px
z-index 10
pointer-events none
opacity 0
border-top-right-radius 2px
border-bottom-right-radius 2px
height 26px
margin-top -26px
line-height 26px
.root--folded .root--folded
@extend .root @extend .root
.header .header
@@ -162,11 +106,7 @@
.header-info--folded-tooltip-path .header-info--folded-tooltip-path
font-size 10px font-size 10px
margin 0 5px margin 0 5px
.folderList-item:hover, .folderList-item--active:hover
.folderList-item-tooltip
opacity 1
.folderList-item-name
padding-left 14px
body[data-theme="dark"] body[data-theme="dark"]
.header-toggleButton .header-toggleButton
.header-addFolderButton .header-addFolderButton

View File

@@ -5,9 +5,7 @@ import { openModal } from 'browser/main/lib/modal'
import PreferencesModal from '../modals/PreferencesModal' import PreferencesModal from '../modals/PreferencesModal'
import ConfigManager from 'browser/main/lib/ConfigManager' import ConfigManager from 'browser/main/lib/ConfigManager'
import StorageItem from './StorageItem' import StorageItem from './StorageItem'
import SideNavFilter from 'browser/components/SideNavFilter'
const electron = require('electron')
const { remote } = electron
class SideNav extends React.Component { class SideNav extends React.Component {
// TODO: should not use electron stuff v0.7 // TODO: should not use electron stuff v0.7
@@ -39,8 +37,8 @@ class SideNav extends React.Component {
let { data, location, config, dispatch } = this.props let { data, location, config, dispatch } = this.props
let isFolded = config.isSideNavFolded let isFolded = config.isSideNavFolded
let isHomeActive = location.pathname.match(/^\/home$/) let isHomeActive = !!location.pathname.match(/^\/home$/)
let isStarredActive = location.pathname.match(/^\/starred$/) let isStarredActive = !!location.pathname.match(/^\/starred$/)
let storageList = data.storageMap.map((storage, key) => { let storageList = data.storageMap.map((storage, key) => {
return <StorageItem return <StorageItem
@@ -64,25 +62,18 @@ class SideNav extends React.Component {
<button styleName='top-menu' <button styleName='top-menu'
onClick={(e) => this.handleMenuButtonClick(e)} onClick={(e) => this.handleMenuButtonClick(e)}
> >
<i className='fa fa-navicon fa-fw'/> <i className='fa fa-navicon fa-fw' />
<span styleName='top-menu-label'>Menu</span> <span styleName='top-menu-label'>Menu</span>
</button> </button>
</div> </div>
<div styleName='menu'> <SideNavFilter
<button styleName={isHomeActive ? 'menu-button--active' : 'menu-button'} isFolded={isFolded}
onClick={(e) => this.handleHomeButtonClick(e)} isHomeActive={isHomeActive}
> handleAllNotesButtonClick={(e) => this.handleHomeButtonClick(e)}
<i className='fa fa-files-o fa-fw'/> isStarredActive={isStarredActive}
<span styleName='menu-button-label'>All Notes</span> handleStarredButtonClick={(e) => this.handleStarredButtonClick(e)}
</button> />
<button styleName={isStarredActive ? 'menu-button--active' : 'menu-button'}
onClick={(e) => this.handleStarredButtonClick(e)}
>
<i className='fa fa-star fa-fw'/>
<span styleName='menu-button-label'>Starred</span>
</button>
</div>
<div styleName='storageList'> <div styleName='storageList'>
{storageList.length > 0 ? storageList : ( {storageList.length > 0 ? storageList : (
@@ -93,8 +84,8 @@ class SideNav extends React.Component {
onClick={(e) => this.handleToggleButtonClick(e)} onClick={(e) => this.handleToggleButtonClick(e)}
> >
{isFolded {isFolded
? <i className='fa fa-angle-double-right'/> ? <i className='fa fa-angle-double-right' />
: <i className='fa fa-angle-double-left'/> : <i className='fa fa-angle-double-left' />
} }
</button> </button>
</div> </div>

View File

@@ -1,9 +1,12 @@
@import('../Detail/DetailVars')
.root .root
absolute bottom left right absolute bottom left right
height $statusBar-height - 1 height $statusBar-height
background-color $ui-backgroundColor background-color $ui-noteDetail-backgroundColor
border-top $ui-border border-top $ui-border
display flex display flex
box-shadow $note-detail-box-shadow
.blank .blank
flex 1 flex 1
@@ -39,7 +42,9 @@
body[data-theme="dark"] body[data-theme="dark"]
.root .root
background-color $ui-dark-backgroundColor background-color $ui-dark-noteDetail-backgroundColor
border-color $ui-dark-borderColor
box-shadow none
.zoom .zoom
border-color $ui-dark-borderColor border-color $ui-dark-borderColor

View File

@@ -2,6 +2,7 @@ import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules' import CSSModules from 'browser/lib/CSSModules'
import styles from './StatusBar.styl' import styles from './StatusBar.styl'
import ZoomManager from 'browser/main/lib/ZoomManager' import ZoomManager from 'browser/main/lib/ZoomManager'
import LastUpdatedString from '../Detail/LastUpdatedString'
const electron = require('electron') const electron = require('electron')
const { remote, ipcRenderer } = electron const { remote, ipcRenderer } = electron
@@ -52,22 +53,23 @@ class StatusBar extends React.Component {
<div className='StatusBar' <div className='StatusBar'
styleName='root' styleName='root'
> >
<div styleName='blank' />
{status.updateReady
? <button onClick={this.updateApp} styleName='update'>
<i styleName='update-icon' className='fa fa-cloud-download' /> Ready to Update!
</button>
: null
}
{/*<button styleName='help'>
<i className='fa fa-info-circle' />
</button>*/}
<button styleName='zoom' <button styleName='zoom'
onClick={(e) => this.handleZoomButtonClick(e)} onClick={(e) => this.handleZoomButtonClick(e)}
> >
<i className='fa fa-search-plus' />&nbsp; <i className='fa fa-search-plus' />&nbsp;
{Math.floor(config.zoom * 100)}% {Math.floor(config.zoom * 100)}%
</button> </button>
<div styleName='blank' />
{status.updateReady
? <button onClick={this.updateApp} styleName='update'>
<i styleName='update-icon' className='fa fa-cloud-download' /> Ready to Update!
</button>
: null
}
<LastUpdatedString date={this.props.date} />
</div> </div>
) )
} }
@@ -77,7 +79,8 @@ StatusBar.contextTypes = {
status: PropTypes.shape({ status: PropTypes.shape({
updateReady: PropTypes.bool.isRequired updateReady: PropTypes.bool.isRequired
}).isRequired, }).isRequired,
config: PropTypes.shape({}).isRequired config: PropTypes.shape({}).isRequired,
date: PropTypes.string
} }
StatusBar.propTypes = { StatusBar.propTypes = {

View File

@@ -1,19 +1,19 @@
.root .root
position relative position relative
background-color $ui-backgroundColor background-color $ui-noteList-backgroundColor
height $topBar-height - 1 height $topBar-height - 1
.root--expanded .root--expanded
@extend .root @extend .root
$control-height = 34px $control-height = 34px
.control .control
position absolute position absolute
top 8px top 13px
left 8px left 8px
right 8px right 8px
height $control-height height $control-height
border $ui-border
border-radius 20px
overflow hidden overflow hidden
display flex display flex
@@ -28,6 +28,7 @@ $control-height = 34px
line-height 32px line-height 32px
width 35px width 35px
color $ui-inactive-text-color color $ui-inactive-text-color
background-color $ui-noteList-backgroundColor
.control-search-input .control-search-input
display block display block
@@ -38,6 +39,7 @@ $control-height = 34px
height 100% height 100%
outline none outline none
border none border none
background-color $ui-noteList-backgroundColor
.control-search-optionList .control-search-optionList
position fixed position fixed
@@ -58,6 +60,7 @@ $control-height = 34px
overflow ellipsis overflow ellipsis
&:hover &:hover
background-color alpha($ui-active-color, 10%) background-color alpha($ui-active-color, 10%)
.control-search-optionList-item-folder .control-search-optionList-item-folder
border-left 4px solid transparent border-left 4px solid transparent
padding 2px 5px padding 2px 5px
@@ -66,40 +69,30 @@ $control-height = 34px
font-size 12px font-size 12px
height 16px height 16px
margin-bottom 4px margin-bottom 4px
.control-search-optionList-item-folder-surfix .control-search-optionList-item-folder-surfix
font-size 10px font-size 10px
margin-left 5px margin-left 5px
color $ui-inactive-text-color color $ui-inactive-text-color
.control-search-optionList-item-type .control-search-optionList-item-type
font-size 12px font-size 12px
color $ui-inactive-text-color color $ui-inactive-text-color
padding-right 3px padding-right 3px
.control-search-optionList-empty .control-search-optionList-empty
height 150px height 150px
color $ui-inactive-text-color color $ui-inactive-text-color
line-height 150px line-height 150px
text-align center text-align center
.control-contextButton
display block
width 20px
height $control-height - 2
navButtonColor()
border-left $ui-border
font-size 14px
line-height 28px
padding 0
&:active
border-color $ui-button--active-backgroundColor
&:hover .control-newPostButton-tooltip
opacity 1
.control-newPostButton .control-newPostButton
display block display block
width 36px width 32px
height $control-height - 2 height $control-height - 2
navButtonColor() navButtonColor()
border-left $ui-border border $ui-border
border-radius 32px
font-size 14px font-size 14px
line-height 28px line-height 28px
padding 0 padding 0
@@ -112,17 +105,18 @@ $control-height = 34px
tooltip() tooltip()
position fixed position fixed
pointer-events none pointer-events none
top 45px top 50px
left 385px left 433px
z-index 10 z-index 200
padding 5px padding 5px
line-height normal line-height normal
border-radius 2px
opacity 0 opacity 0
transition 0.1s transition 0.1s
body[data-theme="dark"] body[data-theme="dark"]
.root, .root--expanded .root, .root--expanded
background-color $ui-dark-backgroundColor background-color $ui-dark-noteList-backgroundColor
.control .control
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
@@ -134,11 +128,13 @@ body[data-theme="dark"]
line-height 32px line-height 32px
width 35px width 35px
color $ui-dark-inactive-text-color color $ui-dark-inactive-text-color
background-color $ui-dark-noteList-backgroundColor
.control-search-input .control-search-input
input input
background-color $dark-background-color background-color $ui-dark-noteList-backgroundColor
color $ui-dark-text-color color $ui-dark-text-color
.control-search-optionList .control-search-optionList
color white color white
background-color $ui-dark-button--hover-backgroundColor background-color $ui-dark-button--hover-backgroundColor
@@ -162,10 +158,10 @@ body[data-theme="dark"]
.control-search-optionList-empty .control-search-optionList-empty
color $ui-inactive-text-color color $ui-inactive-text-color
.control-contextButton,
.control-newPostButton .control-newPostButton
colorDarkDefaultButton() colorDarkDefaultButton()
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
background-color $ui-dark-noteList-backgroundColor
&:active &:active
border-color $ui-dark-button--active-backgroundColor border-color $ui-dark-button--active-backgroundColor

View File

@@ -10,8 +10,6 @@ import ConfigManager from 'browser/main/lib/ConfigManager'
import dataApi from 'browser/main/lib/dataApi' import dataApi from 'browser/main/lib/dataApi'
const OSX = window.process.platform === 'darwin' const OSX = window.process.platform === 'darwin'
const { remote } = require('electron')
const { Menu, MenuItem } = remote
class TopBar extends React.Component { class TopBar extends React.Component {
constructor (props) { constructor (props) {
@@ -71,10 +69,10 @@ class TopBar extends React.Component {
break break
} }
} }
if (storage == null) throw new Error('No storage to create a note') if (storage == null) window.alert('No storage to create a note')
let folder = _.find(storage.folders, {key: params.folderKey}) let folder = _.find(storage.folders, {key: params.folderKey})
if (folder == null) folder = storage.folders[0] if (folder == null) folder = storage.folders[0]
if (folder == null) throw new Error('No folder to craete a note') if (folder == null) window.alert('No folder to create a note')
return { return {
storage, storage,
@@ -192,47 +190,6 @@ class TopBar extends React.Component {
} }
} }
handleContextButtonClick (e) {
let { config } = this.props
let menu = new Menu()
menu.append(new MenuItem({
label: 'Create Markdown Note',
click: (e) => this.createNote('MARKDOWN_NOTE')
}))
menu.append(new MenuItem({
label: 'Create Snippet Note',
click: (e) => this.createNote('SNIPPET_NOTE')
}))
menu.append(new MenuItem({
type: 'separator'
}))
menu.append(new MenuItem({
label: 'Change Default Note',
submenu: [
{
type: 'radio',
label: 'Markdown Note',
checked: config.ui.defaultNote === 'MARKDOWN_NOTE',
click: (e) => this.setDefaultNote('MARKDOWN_NOTE')
},
{
type: 'radio',
label: 'Snippet Note',
checked: config.ui.defaultNote === 'SNIPPET_NOTE',
click: (e) => this.setDefaultNote('SNIPPET_NOTE')
},
{
type: 'radio',
label: 'Always Ask',
checked: config.ui.defaultNote === 'ALWAYS_ASK',
click: (e) => this.setDefaultNote('ALWAYS_ASK')
}
]
}))
menu.popup(remote.getCurrentWindow())
}
createNote (noteType) { createNote (noteType) {
let { dispatch, location } = this.props let { dispatch, location } = this.props
if (noteType !== 'MARKDOWN_NOTE' && noteType !== 'SNIPPET_NOTE') throw new Error('Invalid note type.') if (noteType !== 'MARKDOWN_NOTE' && noteType !== 'SNIPPET_NOTE') throw new Error('Invalid note type.')
@@ -303,8 +260,8 @@ class TopBar extends React.Component {
<span styleName='control-search-optionList-item-folder-surfix'>in {storage.name}</span> <span styleName='control-search-optionList-item-folder-surfix'>in {storage.name}</span>
</div> </div>
{note.type === 'SNIPPET_NOTE' {note.type === 'SNIPPET_NOTE'
? <i styleName='control-search-optionList-item-type' className='fa fa-code'/> ? <i styleName='control-search-optionList-item-type' className='fa fa-code' />
: <i styleName='control-search-optionList-item-type' className='fa fa-file-text-o'/> : <i styleName='control-search-optionList-item-type' className='fa fa-file-text-o' />
}&nbsp; }&nbsp;
{note.title} {note.title}
</div> </div>
@@ -317,7 +274,7 @@ class TopBar extends React.Component {
> >
<div styleName='control'> <div styleName='control'>
<div styleName='control-search'> <div styleName='control-search'>
<i styleName='control-search-icon' className='fa fa-search fa-fw'/> <i styleName='control-search-icon' className='fa fa-search fa-fw' />
<div styleName='control-search-input' <div styleName='control-search-input'
onFocus={(e) => this.handleSearchFocus(e)} onFocus={(e) => this.handleSearchFocus(e)}
onBlur={(e) => this.handleSearchBlur(e)} onBlur={(e) => this.handleSearchBlur(e)}
@@ -344,23 +301,18 @@ class TopBar extends React.Component {
<button styleName='left-search-clearButton' <button styleName='left-search-clearButton'
onClick={(e) => this.handleSearchClearButton(e)} onClick={(e) => this.handleSearchClearButton(e)}
> >
<i className='fa fa-times'/> <i className='fa fa-times' />
</button> </button>
} }
</div> </div>
<button styleName='control-newPostButton' <button styleName='control-newPostButton'
onClick={(e) => this.handleNewPostButtonClick(e)}> onClick={(e) => this.handleNewPostButtonClick(e)}>
<i className='fa fa-plus'/> <i className='fa fa-plus' />
<span styleName='control-newPostButton-tooltip'> <span styleName='control-newPostButton-tooltip'>
New Note {OSX ? '⌘' : '^'} + n Make a Note {OSX ? '⌘' : '^'} + n
</span> </span>
</button> </button>
<button styleName='control-contextButton'
onClick={(e) => this.handleContextButtonClick(e)}
>
<i className='fa fa-caret-down'/>
</button>
</div> </div>
</div> </div>
) )

View File

@@ -92,6 +92,8 @@ body[data-theme="dark"]
font-family inherit !important font-family inherit !important
line-height 1.4em line-height 1.4em
height 100% height 100%
.CodeMirror > div > textarea
margin-bottom -1em
.CodeMirror-focused .CodeMirror-selected .CodeMirror-focused .CodeMirror-selected
background #B1D7FE background #B1D7FE
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection

View File

@@ -10,7 +10,7 @@ let isInitialized = false
export const DEFAULT_CONFIG = { export const DEFAULT_CONFIG = {
zoom: 1, zoom: 1,
isSideNavFolded: false, isSideNavFolded: false,
listWidth: 250, listWidth: 280,
navWidth: 200, navWidth: 200,
sortBy: 'UPDATED_AT', // 'CREATED_AT', 'UPDATED_AT', 'APLHABETICAL' sortBy: 'UPDATED_AT', // 'CREATED_AT', 'UPDATED_AT', 'APLHABETICAL'
listStyle: 'DEFAULT', // 'DEFAULT', 'SMALL' listStyle: 'DEFAULT', // 'DEFAULT', 'SMALL'
@@ -25,6 +25,7 @@ export const DEFAULT_CONFIG = {
}, },
editor: { editor: {
theme: 'default', theme: 'default',
keyMap: 'sublime',
fontSize: '14', fontSize: '14',
fontFamily: 'Monaco, Consolas', fontFamily: 'Monaco, Consolas',
indentType: 'space', indentType: 'space',
@@ -34,7 +35,7 @@ export const DEFAULT_CONFIG = {
preview: { preview: {
fontSize: '14', fontSize: '14',
fontFamily: 'Lato', fontFamily: 'Lato',
codeBlockTheme: 'xcode', codeBlockTheme: 'elegant',
lineNumber: true lineNumber: true
} }
} }

View File

@@ -20,10 +20,10 @@ class ModalBase extends React.Component {
render () { render () {
return ( return (
<div className={'ModalBase' + (this.state.isHidden ? ' hide' : '')}> <div className={'ModalBase' + (this.state.isHidden ? ' hide' : '')}>
<div onClick={(e) => this.close(e)} className='modalBack'/> <div onClick={(e) => this.close(e)} className='modalBack' />
{this.state.component == null ? null : ( {this.state.component == null ? null : (
<Provider store={store}> <Provider store={store}>
<this.state.component {...this.state.componentProps} close={this.close}/> <this.state.component {...this.state.componentProps} close={this.close} />
</Provider> </Provider>
)} )}
</div> </div>
@@ -33,7 +33,7 @@ class ModalBase extends React.Component {
let el = document.createElement('div') let el = document.createElement('div')
document.body.appendChild(el) document.body.appendChild(el)
let modalBase = ReactDOM.render(<ModalBase/>, el) let modalBase = ReactDOM.render(<ModalBase />, el)
export function openModal (component, props) { export function openModal (component, props) {
if (modalBase == null) { return } if (modalBase == null) { return }

View File

@@ -75,24 +75,27 @@ class CreateFolderModal extends React.Component {
onKeyDown={(e) => this.handleKeyDown(e)} onKeyDown={(e) => this.handleKeyDown(e)}
> >
<div styleName='header'> <div styleName='header'>
<div styleName='title'>New Folder</div> <div styleName='title'>Create new folder</div>
</div> </div>
<button styleName='closeButton' <button styleName='close' onClick={(e) => this.handleCloseButtonClick(e)}>
onClick={(e) => this.handleCloseButtonClick(e)} <div styleName='close-mark'>X</div>
>Close</button> <div styleName='close-text'>esc</div>
</button>
<div styleName='control'> <div styleName='control'>
<input styleName='control-input' <div styleName='control-folder'>
placeholder='Folder Name' <div styleName='control-folder-label'>Folder name</div>
ref='name' <input styleName='control-folder-input'
value={this.state.name} ref='name'
onChange={(e) => this.handleChange(e)} value={this.state.name}
onKeyDown={(e) => this.handleInputKeyDown(e)} onChange={(e) => this.handleChange(e)}
/> onKeyDown={(e) => this.handleInputKeyDown(e)}
/>
</div>
<button styleName='control-confirmButton' <button styleName='control-confirmButton'
onClick={(e) => this.handleConfirmButtonClick(e)} onClick={(e) => this.handleConfirmButtonClick(e)}
> >
Confirm Create Folder
</button> </button>
</div> </div>
</div> </div>

View File

@@ -1,47 +1,52 @@
.root .root
modal() modal()
max-width 340px width 700px
height 200px
overflow hidden overflow hidden
position relative position relative
padding 0 40px
.header .header
height 50px height 50px
margin-bottom 10px
margin-top 10px
font-size 18px font-size 18px
line-height 50px line-height 50px
padding 0 15px
background-color $ui-backgroundColor background-color $ui-backgroundColor
border-bottom solid 1px $ui-borderColor
color $ui-text-color color $ui-text-color
.closeButton .close-mark
font-size 15px
.close
height 50px
position absolute position absolute
top 10px background-color transparent
color $ui-inactive-text-color
border none
top 7px
right 10px right 10px
height 30px
width 0 25px
border $ui-border
border-radius 2px
color $ui-text-color
colorDefaultButton()
.control
padding 25px 15px 15px
text-align center text-align center
width top-bar--height
height top-bar--height
.control-input .control-folder-label
text-align left
font-size 14px
color $ui-text-color
.control-folder-input
display block display block
height 30px height 30px
width 240px width 620px
padding 0 5px padding 0 5px
margin 0 auto 15px margin 10px auto 15px
border none border 1px solid #C9C9C9 // TODO: use variable.
border-bottom solid 1px $border-color border-radius 5px
border-radius 2px
background-color transparent background-color transparent
outline none outline none
vertical-align middle vertical-align middle
font-size 18px font-size 18px
text-align center
&:disabled &:disabled
background-color $ui-input--disabled-backgroundColor background-color $ui-input--disabled-backgroundColor
&:focus, &:active &:focus, &:active
@@ -50,21 +55,35 @@
.control-confirmButton .control-confirmButton
display block display block
height 30px height 30px
width 620px
border none border none
border-radius 2px border-radius 5px
padding 0 25px padding 0 25px
margin 0 auto margin 20px auto
font-size 14px
colorPrimaryButton() colorPrimaryButton()
body[data-theme="dark"] body[data-theme="dark"]
.root .root
modalDark() modalDark()
width 700px
height 200px
overflow hidden
position relative
padding 0 40px
.header .header
background-color $ui-dark-button--hover-backgroundColor background-color transparent
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
color $ui-dark-text-color color $ui-dark-text-color
.control-folder-label
color $ui-dark-text-color
.control-folder-input
border 1px solid #C9C9C9 // TODO: use variable.
color white
.closeButton .closeButton
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
color $ui-dark-text-color color $ui-dark-text-color
@@ -72,8 +91,3 @@ body[data-theme="dark"]
.description .description
color $ui-inactive-text-color color $ui-inactive-text-color
.control-input
border-color $ui-dark-borderColor
color white

View File

@@ -33,13 +33,13 @@ export default class DeleteArticleModal extends React.Component {
render () { render () {
return ( return (
<div className='DeleteArticleModal modal'> <div className='DeleteArticleModal modal'>
<div className='title'><i className='fa fa-fw fa-trash'/> Delete an article.</div> <div className='title'><i className='fa fa-fw fa-trash' /> Delete an article.</div>
<div className='message'>Do you really want to delete?</div> <div className='message'>Do you really want to delete?</div>
<div className='control'> <div className='control'>
<button ref='no' onClick={(e) => this.handleNoButtonClick(e)}><i className='fa fa-fw fa-close'/> No</button> <button ref='no' onClick={(e) => this.handleNoButtonClick(e)}><i className='fa fa-fw fa-close' /> No</button>
<button ref='yes' onClick={(e) => this.handleYesButtonClick(e)} className='danger'><i className='fa fa-fw fa-check'/> Yes</button> <button ref='yes' onClick={(e) => this.handleYesButtonClick(e)} className='danger'><i className='fa fa-fw fa-check' /> Yes</button>
</div> </div>
</div> </div>
) )

View File

@@ -1,11 +1,10 @@
import React, { PropTypes } from 'react' import React from 'react'
import CSSModules from 'browser/lib/CSSModules' import CSSModules from 'browser/lib/CSSModules'
import styles from './InitModal.styl' import styles from './InitModal.styl'
import dataApi from 'browser/main/lib/dataApi' import dataApi from 'browser/main/lib/dataApi'
import store from 'browser/main/store' import store from 'browser/main/store'
import { hashHistory } from 'react-router' import { hashHistory } from 'react-router'
import _ from 'lodash' import _ from 'lodash'
import keygen from 'browser/lib/keygen'
const CSON = require('@rokt33r/season') const CSON = require('@rokt33r/season')
const path = require('path') const path = require('path')
@@ -197,7 +196,7 @@ class InitModal extends React.Component {
render () { render () {
if (this.state.isLoading) { if (this.state.isLoading) {
return <div styleName='root--loading'> return <div styleName='root--loading'>
<i styleName='spinner' className='fa fa-spin fa-spinner'/> <i styleName='spinner' className='fa fa-spin fa-spinner' />
<div styleName='loadingMessage'>Preparing initialization...</div> <div styleName='loadingMessage'>Preparing initialization...</div>
</div> </div>
} }
@@ -235,7 +234,7 @@ class InitModal extends React.Component {
{this.state.legacyStorageExists && {this.state.legacyStorageExists &&
<div styleName='body-migration'> <div styleName='body-migration'>
<label><input type='checkbox' checked={this.state.migrationRequested} onChange={(e) => this.handleMigrationRequestedChange(e)}/> Migrate old data from the legacy app v0.5</label> <label><input type='checkbox' checked={this.state.migrationRequested} onChange={(e) => this.handleMigrationRequestedChange(e)} /> Migrate old data from the legacy app v0.5</label>
</div> </div>
} }
@@ -247,7 +246,7 @@ class InitModal extends React.Component {
> >
{this.state.isSending {this.state.isSending
? <span> ? <span>
<i className='fa fa-spin fa-spinner'/> Loading... <i className='fa fa-spin fa-spinner' /> Loading...
</span> </span>
: 'Let\'s Go!' : 'Let\'s Go!'
} }

View File

@@ -1,4 +1,4 @@
import React, { PropTypes } from 'react' import React from 'react'
import CSSModules from 'browser/lib/CSSModules' import CSSModules from 'browser/lib/CSSModules'
import styles from './NewNoteModal.styl' import styles from './NewNoteModal.styl'
import dataApi from 'browser/main/lib/dataApi' import dataApi from 'browser/main/lib/dataApi'
@@ -100,7 +100,7 @@ class NewNoteModal extends React.Component {
onKeyDown={(e) => this.handleKeyDown(e)} onKeyDown={(e) => this.handleKeyDown(e)}
> >
<div styleName='header'> <div styleName='header'>
<div styleName='title'>New Note</div> <div styleName='title'>Make a Note</div>
</div> </div>
<button styleName='closeButton' <button styleName='closeButton'
onClick={(e) => this.handleCloseButtonClick(e)} onClick={(e) => this.handleCloseButtonClick(e)}
@@ -114,8 +114,8 @@ class NewNoteModal extends React.Component {
> >
<i styleName='control-button-icon' <i styleName='control-button-icon'
className='fa fa-file-text-o' className='fa fa-file-text-o'
/><br/> /><br />
<span styleName='control-button-label'>Markdown Note</span><br/> <span styleName='control-button-label'>Markdown Note</span><br />
<span styleName='control-button-description'>It is good for any type of documents. Check List, Code block and Latex block are available.</span> <span styleName='control-button-description'>It is good for any type of documents. Check List, Code block and Latex block are available.</span>
</button> </button>
@@ -126,14 +126,14 @@ class NewNoteModal extends React.Component {
> >
<i styleName='control-button-icon' <i styleName='control-button-icon'
className='fa fa-code' className='fa fa-code'
/><br/> /><br />
<span styleName='control-button-label'>Snippet Note</span><br/> <span styleName='control-button-label'>Snippet Note</span><br />
<span styleName='control-button-description'>This format is specialized on managing snippets like Gist. Multiple snippets can be grouped as a note. <span styleName='control-button-description'>This format is specialized on managing snippets like Gist. Multiple snippets can be grouped as a note.
</span> </span>
</button> </button>
</div> </div>
<div styleName='description'><i className='fa fa-arrows-h'/> Tab to switch format</div> <div styleName='description'><i className='fa fa-arrows-h' /> Tab to switch format</div>
</div> </div>
) )

View File

@@ -1,39 +1,44 @@
@import('./Tab')
.root .root
padding 15px padding 15px
color $ui-text-color color $ui-text-color
margin-bottom 30px
.group .group
margin-bottom 45px margin-bottom 45px
.group-header .group-header
font-size 24px @extend .header
color $ui-text-color color $ui-text-color
padding 5px
border-bottom $default-border
margin-bottom 15px
.group-header2 .group-header2
font-size 18px font-size 20px
color $ui-text-color color $ui-text-color
padding 5px
margin-bottom 15px margin-bottom 15px
margin-top 30px
.group-section .group-section
margin-bottom 15px margin-bottom 20px
display flex display flex
line-height 30px line-height 30px
.group-section-label .group-section-label
width 150px width 150px
text-align right text-align left
margin-right 10px margin-right 10px
font-size 14px font-size 14px
.group-section-control .group-section-control
flex 1 flex 1
.group-section-control-input .group-section-control-input
height 30px height 30px
vertical-align middle vertical-align middle
width 150px width 400px
font-size 12px font-size $tab--button-font-size
border solid 1px $border-color border solid 1px $border-color
border-radius 2px border-radius $tab--input-border-radius
padding 0 5px padding 0 5px
&:disabled &:disabled
background-color $ui-input--disabled-backgroundColor background-color $ui-input--disabled-backgroundColor
@@ -45,7 +50,6 @@
padding-left 15px padding-left 15px
.group-control .group-control
border-top $default-border
padding-top 10px padding-top 10px
box-sizing border-box box-sizing border-box
height 40px height 40px
@@ -56,22 +60,26 @@
line-height 30px line-height 30px
padding 0 5px padding 0 5px
float right float right
.group-control-leftButton .group-control-leftButton
float left
colorDefaultButton() colorDefaultButton()
border $default-border border none
border-radius 2px border-radius 5px
height 30px font-size $tab--button-font-size
height $tab--button-height
padding 0 15px padding 0 15px
margin-right 5px margin-right 10px
.group-control-rightButton .group-control-rightButton
float right float right
colorPrimaryButton() colorPrimaryButton()
border none border none
border-radius 2px border-radius $tab--button-border-radius
height 30px font-size $tab--button-font-size
height $tab--button-height
padding 0 15px padding 0 15px
margin-right 5px margin-right 10px
.group-hint .group-hint
border $ui-border border $ui-border
padding 10px 15px padding 10px 15px
@@ -86,6 +94,14 @@
p p
line-height 1.2 line-height 1.2
.note-for-keymap
margin-left: 10px
font-size: 12px
colorDarkControl()
border-color $ui-dark-borderColor
background-color $ui-dark-backgroundColor
color $ui-dark-text-color
body[data-theme="dark"] body[data-theme="dark"]
.root .root
color $ui-dark-text-color color $ui-dark-text-color
@@ -108,6 +124,7 @@ body[data-theme="dark"]
.group-control-rightButton .group-control-rightButton
colorDarkPrimaryButton() colorDarkPrimaryButton()
.group-hint .group-hint
border-color $ui-dark-borderColor colorDarkControl()
background-color $ui-dark-backgroundColor .group-section-control
color $ui-dark-text-color select, .group-section-control-input
colorDarkControl()

View File

@@ -0,0 +1,154 @@
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './ConfigTab.styl'
import ConfigManager from 'browser/main/lib/ConfigManager'
import store from 'browser/main/store'
const electron = require('electron')
const ipc = electron.ipcRenderer
class HotkeyTab extends React.Component {
constructor (props) {
super(props)
this.state = {
isHotkeyHintOpen: false,
config: props.config
}
}
componentDidMount () {
this.handleSettingDone = () => {
this.setState({keymapAlert: {
type: 'success',
message: 'Successfully applied!'
}})
}
this.handleSettingError = (err) => {
this.setState({keymapAlert: {
type: 'error',
message: err.message != null ? err.message : 'Error occurs!'
}})
}
ipc.addListener('APP_SETTING_DONE', this.handleSettingDone)
ipc.addListener('APP_SETTING_ERROR', this.handleSettingError)
}
componentWillUnmount () {
ipc.removeListener('APP_SETTING_DONE', this.handleSettingDone)
ipc.removeListener('APP_SETTING_ERROR', this.handleSettingError)
}
handleSaveButtonClick (e) {
let newConfig = {
hotkey: this.state.config.hotkey
}
ConfigManager.set(newConfig)
store.dispatch({
type: 'SET_UI',
config: newConfig
})
}
handleHintToggleButtonClick (e) {
this.setState({
isHotkeyHintOpen: !this.state.isHotkeyHintOpen
})
}
handleHotkeyChange (e) {
let { config } = this.state
config.hotkey = {
toggleFinder: this.refs.toggleFinder.value,
toggleMain: this.refs.toggleMain.value
}
this.setState({
config
})
}
render () {
let keymapAlert = this.state.keymapAlert
let keymapAlertElement = keymapAlert != null
? <p className={`alert ${keymapAlert.type}`}>
{keymapAlert.message}
</p>
: null
let { config } = this.state
return (
<div styleName='root'>
<div styleName='group'>
<div styleName='group-header'>Hotkey</div>
<div styleName='group-section'>
<div styleName='group-section-label'>Toggle Main</div>
<div styleName='group-section-control'>
<input styleName='group-section-control-input'
onChange={(e) => this.handleHotkeyChange(e)}
ref='toggleMain'
value={config.hotkey.toggleMain}
type='text'
/>
</div>
</div>
<div styleName='group-section'>
<div styleName='group-section-label'>Toggle Finder(popup)</div>
<div styleName='group-section-control'>
<input styleName='group-section-control-input'
onChange={(e) => this.handleHotkeyChange(e)}
ref='toggleFinder'
value={config.hotkey.toggleFinder}
type='text'
/>
</div>
</div>
<div styleName='group-control'>
<button styleName='group-control-leftButton'
onClick={(e) => this.handleHintToggleButtonClick(e)}
>
{this.state.isHotkeyHintOpen
? 'Hide Hint'
: 'Hint?'
}
</button>
<button styleName='group-control-rightButton'
onClick={(e) => this.handleSaveButtonClick(e)}>Save
</button>
{keymapAlertElement}
</div>
{this.state.isHotkeyHintOpen &&
<div styleName='group-hint'>
<p>Available Keys</p>
<ul>
<li><code>0</code> to <code>9</code></li>
<li><code>A</code> to <code>Z</code></li>
<li><code>F1</code> to <code>F24</code></li>
<li>Punctuations like <code>~</code>, <code>!</code>, <code>@</code>, <code>#</code>, <code>$</code>, etc.</li>
<li><code>Plus</code></li>
<li><code>Space</code></li>
<li><code>Backspace</code></li>
<li><code>Delete</code></li>
<li><code>Insert</code></li>
<li><code>Return</code> (or <code>Enter</code> as alias)</li>
<li><code>Up</code>, <code>Down</code>, <code>Left</code> and <code>Right</code></li>
<li><code>Home</code> and <code>End</code></li>
<li><code>PageUp</code> and <code>PageDown</code></li>
<li><code>Escape</code> (or <code>Esc</code> for short)</li>
<li><code>VolumeUp</code>, <code>VolumeDown</code> and <code>VolumeMute</code></li>
<li><code>MediaNextTrack</code>, <code>MediaPreviousTrack</code>, <code>MediaStop</code> and <code>MediaPlayPause</code></li>
</ul>
</div>
}
</div>
</div>
)
}
}
HotkeyTab.propTypes = {
dispatch: PropTypes.func
}
export default CSSModules(HotkeyTab, styles)

View File

@@ -1,4 +1,4 @@
import React, { PropTypes } from 'react' import React from 'react'
import CSSModules from 'browser/lib/CSSModules' import CSSModules from 'browser/lib/CSSModules'
import styles from './InfoTab.styl' import styles from './InfoTab.styl'
@@ -22,17 +22,24 @@ class InfoTab extends React.Component {
render () { render () {
return ( return (
<div styleName='root'> <div styleName='root'>
<div styleName='header'>Info</div>
<div styleName='top'> <div styleName='top'>
<img styleName='icon' src='../resources/app.png' width='150' height='150'/> <div styleName='icon-space'>
<div styleName='appId'>Boostnote {appVersion}</div> <img styleName='icon' src='../resources/app.png' width='92' height='92' />
<div styleName='description'> <div styleName='icon-right'>
A simple markdown/snippet note app for developer. <div styleName='appId'>Boostnote {appVersion}</div>
<div styleName='description'>
A simple markdown/snippet note app for developer.
</div>
</div>
</div> </div>
<div styleName='clear' />
<div styleName='madeBy'>Made by&nbsp; <div styleName='madeBy'>Made by&nbsp;
<a href='http://maisin.co/' <a href='http://maisin.co/'
onClick={(e) => this.handleLinkClick(e)} onClick={(e) => this.handleLinkClick(e)}
>MAISIN&CO.</a></div> >MAISIN&CO.</a></div>
<div styleName='copyright'>Copyright 2016 MAISIN&CO. All rights reserved.</div> <div styleName='copyright'>Copyright 2017 MAISIN&CO. All rights reserved.</div>
</div> </div>
<ul styleName='list'> <ul styleName='list'>
<li> <li>

View File

@@ -1,3 +1,5 @@
@import('./Tab')
.root .root
padding 15px padding 15px
white-space pre white-space pre
@@ -5,27 +7,39 @@
color $ui-text-color color $ui-text-color
width 100% width 100%
.clear
clear both
.top .top
text-align center text-align left
margin-bottom 25px margin-bottom 20px
.icon-space
margin 20px 0
height 100px
.icon
display inline-block
vertical-align middle
.icon-right
display inline-block
vertical-align middle
margin-left 20px
.appId .appId
font-size 24px font-size 24px
margin-bottom 13px
.description .description
overflow hidden
white-space normal
line-height 1.5
margin 5px auto 10px
font-size 14px font-size 14px
text-align center
.madeBy .madeBy
font-size 12px font-size 14px
$ui-inactive-text-color $ui-inactive-text-color
.copyright .copyright
font-size 12px font-size 14px
$ui-inactive-text-color $ui-inactive-text-color
.list .list
@@ -36,7 +50,7 @@
body[data-theme="dark"] body[data-theme="dark"]
.root .root
color $ui-dark-text-color color $tab--dark-text-color
.madeBy .madeBy
color $ui-dark-inactive-text-color color $ui-dark-inactive-text-color

View File

@@ -1,51 +1,93 @@
@import('./Tab')
top-bar--height = 50px
.root .root
modal() modal()
max-width 540px max-width 800px
min-height 400px min-height 500px
height 80% height 80%
overflow hidden overflow hidden
position relative position relative
.nav .top-bar
absolute top left right absolute top left right
height 50px height top-bar--height
background-color $ui-backgroundColor background-color $ui-backgroundColor
border-bottom solid 1px $ui-borderColor border-bottom solid 1px $ui-borderColor
p
text-align center
font-size 18px
line-height top-bar--height
.top-bar-close
position absolute
background-color transparent
color $ui-inactive-text-color
border none
top 0
right 0
text-align center
width top-bar--height
height top-bar--height
.nav
absolute top left right
top top-bar--height
left 0
width 140px
margin-left 30px
margin-top 20px
background-color $ui-backgroundColor
.nav-button .nav-button
width 80px font-size 14px
height 50px text-align left
width 100px
margin 4px 0
padding 7px 0
padding-left 7px
border none border none
border-radius 3px
background-color transparent background-color transparent
color #939395 color $ui-text-color
font-size 14px font-size 14px
&:hover &:hover
color #515151 color $ui-active-color
.nav-button--active .nav-button--active
@extend .nav-button @extend .nav-button
color #6AA5E9 color white
background-color $ui-active-color
&:hover &:hover
color #6AA5E9 color white
.nav-button-icon .nav-button-icon
display block display block
.content .content
absolute left right bottom absolute left right bottom
top 50px top top-bar--height
left 140px
margin-top 10px
overflow-y auto overflow-y auto
body[data-theme="dark"] body[data-theme="dark"]
.root .root
modalDark() modalDark()
.top-bar
background-color transparent
border-color #4A4D52
p
color $tab--dark-text-color
.nav .nav
background-color $ui-dark-button--hover-backgroundColor background-color transparent
border-color $ui-dark-borderColor border-color $ui-dark-borderColor
.nav-button .nav-button
background-color transparent background-color transparent
color #939395 color $tab--dark-text-color
&:hover &:hover
color $ui-dark-text-color color $ui-dark-text-color

View File

@@ -106,7 +106,10 @@ class UnstyledFolderItem extends React.Component {
const popover = { position: 'absolute', zIndex: 2 } const popover = { position: 'absolute', zIndex: 2 }
const cover = { const cover = {
position: 'fixed', position: 'fixed',
top: 0, right: 0, bottom: 0, left: 0 top: 0,
right: 0,
bottom: 0,
left: 0
} }
const pickerStyle = Object.assign({}, { const pickerStyle = Object.assign({}, {
position: 'absolute' position: 'absolute'
@@ -137,7 +140,7 @@ class UnstyledFolderItem extends React.Component {
</div> </div>
: null : null
} }
<i className='fa fa-square'/> <i className='fa fa-square' />
</button> </button>
<input styleName='folderList-item-left-nameInput' <input styleName='folderList-item-left-nameInput'
value={this.state.folder.name} value={this.state.folder.name}
@@ -300,10 +303,10 @@ class StorageItem extends React.Component {
}) })
if (index === 0) { if (index === 0) {
let { storage, dispatch } = this.props let { storage } = this.props
dataApi.removeStorage(storage.key) dataApi.removeStorage(storage.key)
.then(() => { .then(() => {
dispatch({ store.dispatch({
type: 'REMOVE_STORAGE', type: 'REMOVE_STORAGE',
storageKey: storage.key storageKey: storage.key
}) })
@@ -368,17 +371,17 @@ class StorageItem extends React.Component {
: <div styleName='header-label' : <div styleName='header-label'
onClick={(e) => this.handleLabelClick(e)} onClick={(e) => this.handleLabelClick(e)}
> >
<i className='fa fa-folder-open'/>&nbsp; <i className='fa fa-folder-open' />&nbsp;
{storage.name}&nbsp; {storage.name}&nbsp;
<span styleName='header-label-path'>({storage.path})</span>&nbsp; <span styleName='header-label-path'>({storage.path})</span>&nbsp;
<i styleName='header-label-editButton' className='fa fa-pencil'/> <i styleName='header-label-editButton' className='fa fa-pencil' />
</div> </div>
} }
<div styleName='header-control'> <div styleName='header-control'>
<button styleName='header-control-button' <button styleName='header-control-button'
onClick={(e) => this.handleNewFolderButtonClick(e)} onClick={(e) => this.handleNewFolderButtonClick(e)}
> >
<i className='fa fa-plus'/> <i className='fa fa-plus' />
<span styleName='header-control-button-tooltip' <span styleName='header-control-button-tooltip'
style={{left: -20}} style={{left: -20}}
>Add Folder</span> >Add Folder</span>
@@ -386,7 +389,7 @@ class StorageItem extends React.Component {
<button styleName='header-control-button' <button styleName='header-control-button'
onClick={(e) => this.handleExternalButtonClick(e)} onClick={(e) => this.handleExternalButtonClick(e)}
> >
<i className='fa fa-external-link'/> <i className='fa fa-external-link' />
<span styleName='header-control-button-tooltip' <span styleName='header-control-button-tooltip'
style={{left: -50}} style={{left: -50}}
>Open Storage folder</span> >Open Storage folder</span>
@@ -394,7 +397,7 @@ class StorageItem extends React.Component {
<button styleName='header-control-button' <button styleName='header-control-button'
onClick={(e) => this.handleUnlinkButtonClick(e)} onClick={(e) => this.handleUnlinkButtonClick(e)}
> >
<i className='fa fa-unlink'/> <i className='fa fa-unlink' />
<span styleName='header-control-button-tooltip' <span styleName='header-control-button-tooltip'
style={{left: -10}} style={{left: -10}}
>Unlink</span> >Unlink</span>

View File

@@ -63,6 +63,7 @@ class StoragesTab extends React.Component {
}) })
return ( return (
<div styleName='list'> <div styleName='list'>
<div styleName='header'>Storages</div>
{storageList.length > 0 {storageList.length > 0
? storageList ? storageList
: <div styleName='list-empty'>No storage found.</div> : <div styleName='list-empty'>No storage found.</div>
@@ -71,7 +72,7 @@ class StoragesTab extends React.Component {
<button styleName='list-control-addStorageButton' <button styleName='list-control-addStorageButton'
onClick={(e) => this.handleAddStorageButton(e)} onClick={(e) => this.handleAddStorageButton(e)}
> >
<i className='fa fa-plus'/> Add Storage <i className='fa fa-plus' /> Add Storage
</button> </button>
</div> </div>
</div> </div>

View File

@@ -1,3 +1,5 @@
@import('./Tab')
.root .root
padding 15px padding 15px
color $ui-text-color color $ui-text-color
@@ -26,11 +28,12 @@
.list-control .list-control
height 30px height 30px
.list-control-addStorageButton .list-control-addStorageButton
height 30px height $tab--button-height
padding 0 15px padding 0 15px
border $ui-border border $ui-border
colorDefaultButton() colorDefaultButton()
border-radius 2px font-size $tab--button-font-size
border-radius $tab--button-border-radius
.addStorage .addStorage
margin-bottom 15px margin-bottom 15px

View File

@@ -0,0 +1,18 @@
/**
* Common style for tabs on config modal.
*/
$tab--input-border-radius = 5px
$tab--button-border-radius = 5px
$tab--button-height = 40px
$tab--button-font-size = 14px
$tab--dark-text-color = #E5E5E5
.header
font-size 24px
margin-bottom 30px
body[data-theme="dark"]
.header
color $tab--dark-text-color

View File

@@ -1,107 +1,21 @@
import React, { PropTypes } from 'react' import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules' import CSSModules from 'browser/lib/CSSModules'
import styles from './ConfigTab.styl' import styles from './ConfigTab.styl'
import hljsTheme from 'browser/lib/hljsThemes'
import ConfigManager from 'browser/main/lib/ConfigManager' import ConfigManager from 'browser/main/lib/ConfigManager'
import store from 'browser/main/store' import store from 'browser/main/store'
import consts from 'browser/lib/consts' import consts from 'browser/lib/consts'
const electron = require('electron')
const ipc = electron.ipcRenderer
const OSX = global.process.platform === 'darwin' const OSX = global.process.platform === 'darwin'
class ConfigTab extends React.Component { class UiTab extends React.Component {
constructor (props) { constructor (props) {
super(props) super(props)
this.state = { this.state = {
isHotkeyHintOpen: false,
config: props.config config: props.config
} }
} }
componentDidMount () {
this.handleSettingDone = () => {
this.setState({keymapAlert: {
type: 'success',
message: 'Successfully applied!'
}})
}
this.handleSettingError = (err) => {
this.setState({keymapAlert: {
type: 'error',
message: err.message != null ? err.message : 'Error occurs!'
}})
}
ipc.addListener('APP_SETTING_DONE', this.handleSettingDone)
ipc.addListener('APP_SETTING_ERROR', this.handleSettingError)
}
componentWillUnmount () {
ipc.removeListener('APP_SETTING_DONE', this.handleSettingDone)
ipc.removeListener('APP_SETTING_ERROR', this.handleSettingError)
}
handleSaveButtonClick (e) {
let newConfig = {
hotkey: this.state.config.hotkey
}
ConfigManager.set(newConfig)
store.dispatch({
type: 'SET_UI',
config: newConfig
})
}
handleKeyDown (e) {
if (e.keyCode === 13) {
this.submitHotKey()
}
}
handleConfigKeyDown (e) {
if (e.keyCode === 13) {
this.submitConfig()
}
}
handleLineNumberingClick (e) {
let config = this.state.config
config['preview-line-number'] = e.target.checked
this.setState({
config
})
}
handleDisableDirectWriteClick (e) {
let config = this.state.config
config['disable-direct-write'] = e.target.checked
this.setState({
config
})
}
handleHintToggleButtonClick (e) {
this.setState({
isHotkeyHintOpen: !this.state.isHotkeyHintOpen
})
}
handleHotkeyChange (e) {
let { config } = this.state
config.hotkey = {
toggleFinder: this.refs.toggleFinder.value,
toggleMain: this.refs.toggleMain.value
}
this.setState({
config
})
}
handleUIChange (e) { handleUIChange (e) {
let { config } = this.state let { config } = this.state
@@ -117,7 +31,8 @@ class ConfigTab extends React.Component {
fontFamily: this.refs.editorFontFamily.value, fontFamily: this.refs.editorFontFamily.value,
indentType: this.refs.editorIndentType.value, indentType: this.refs.editorIndentType.value,
indentSize: this.refs.editorIndentSize.value, indentSize: this.refs.editorIndentSize.value,
switchPreview: this.refs.editorSwitchPreview.value switchPreview: this.refs.editorSwitchPreview.value,
keyMap: this.refs.editorKeyMap.value
} }
config.preview = { config.preview = {
fontSize: this.refs.previewFontSize.value, fontSize: this.refs.previewFontSize.value,
@@ -126,13 +41,11 @@ class ConfigTab extends React.Component {
lineNumber: this.refs.previewLineNumber.checked lineNumber: this.refs.previewLineNumber.checked
} }
this.setState({ this.setState({ config })
config
})
} }
handleSaveUIClick (e) { handleSaveUIClick (e) {
let newConfig = { const newConfig = {
ui: this.state.config.ui, ui: this.state.config.ui,
editor: this.state.config.editor, editor: this.state.config.editor,
preview: this.state.config.preview preview: this.state.config.preview
@@ -147,85 +60,17 @@ class ConfigTab extends React.Component {
} }
render () { render () {
let keymapAlert = this.state.keymapAlert const themes = consts.THEMES
let keymapAlertElement = keymapAlert != null const { config } = this.state
? <p className={`alert ${keymapAlert.type}`}>
{keymapAlert.message}
</p>
: null
let themes = consts.THEMES
let hljsThemeList = hljsTheme()
let { config } = this.state
return ( return (
<div styleName='root'> <div styleName='root'>
<div styleName='group'>
<div styleName='group-header'>Hotkey</div>
<div styleName='group-section'>
<div styleName='group-section-label'>Toggle Main</div>
<div styleName='group-section-control'>
<input styleName='group-section-control-input'
onChange={(e) => this.handleHotkeyChange(e)}
ref='toggleMain'
value={config.hotkey.toggleMain}
type='text'
/>
</div>
</div>
<div styleName='group-section'>
<div styleName='group-section-label'>Toggle Finder(popup)</div>
<div styleName='group-section-control'>
<input styleName='group-section-control-input'
onChange={(e) => this.handleHotkeyChange(e)}
ref='toggleFinder'
value={config.hotkey.toggleFinder}
type='text'
/>
</div>
</div>
<div styleName='group-control'>
<button styleName='group-control-leftButton'
onClick={(e) => this.handleHintToggleButtonClick(e)}
>
{this.state.isHotkeyHintOpen
? 'Hide Hint'
: 'Show Hint'
}
</button>
<button styleName='group-control-rightButton'
onClick={(e) => this.handleSaveButtonClick(e)}>Save Hotkey
</button>
{keymapAlertElement}
</div>
{this.state.isHotkeyHintOpen &&
<div styleName='group-hint'>
<p>Available Keys</p>
<ul>
<li><code>0</code> to <code>9</code></li>
<li><code>A</code> to <code>Z</code></li>
<li><code>F1</code> to <code>F24</code></li>
<li>Punctuations like <code>~</code>, <code>!</code>, <code>@</code>, <code>#</code>, <code>$</code>, etc.</li>
<li><code>Plus</code></li>
<li><code>Space</code></li>
<li><code>Backspace</code></li>
<li><code>Delete</code></li>
<li><code>Insert</code></li>
<li><code>Return</code> (or <code>Enter</code> as alias)</li>
<li><code>Up</code>, <code>Down</code>, <code>Left</code> and <code>Right</code></li>
<li><code>Home</code> and <code>End</code></li>
<li><code>PageUp</code> and <code>PageDown</code></li>
<li><code>Escape</code> (or <code>Esc</code> for short)</li>
<li><code>VolumeUp</code>, <code>VolumeDown</code> and <code>VolumeMute</code></li>
<li><code>MediaNextTrack</code>, <code>MediaPreviousTrack</code>, <code>MediaStop</code> and <code>MediaPlayPause</code></li>
</ul>
</div>
}
</div>
<div styleName='group'> <div styleName='group'>
<div styleName='group-header'>UI</div> <div styleName='group-header'>UI</div>
<div styleName='group-header2'>Theme</div>
<div styleName='group-section'> <div styleName='group-section'>
<div styleName='group-section-label'>Theme</div>
<div styleName='group-section-control'> <div styleName='group-section-control'>
<select value={config.ui.theme} <select value={config.ui.theme}
onChange={(e) => this.handleUIChange(e)} onChange={(e) => this.handleUIChange(e)}
@@ -334,6 +179,23 @@ class ConfigTab extends React.Component {
</select> </select>
</div> </div>
</div> </div>
<div styleName='group-section'>
<div styleName='group-section-label'>
Editor Keymap
</div>
<div styleName='group-section-control'>
<select value={config.editor.keyMap}
ref='editorKeyMap'
onChange={(e) => this.handleUIChange(e)}
>
<option value='sublime'>default</option>
<option value='vim'>vim</option>
</select>
<span styleName='note-for-keymap'>Please reload boostnote after you change the keymap</span>
</div>
</div>
<div styleName='group-header2'>Preview</div> <div styleName='group-header2'>Preview</div>
<div styleName='group-section'> <div styleName='group-section'>
<div styleName='group-section-label'> <div styleName='group-section-label'>
@@ -369,8 +231,8 @@ class ConfigTab extends React.Component {
onChange={(e) => this.handleUIChange(e)} onChange={(e) => this.handleUIChange(e)}
> >
{ {
hljsThemeList.map((theme) => { themes.map((theme) => {
return (<option value={theme.name} key={theme.name}>{theme.caption}</option>) return (<option value={theme} key={theme}>{theme}</option>)
}) })
} }
</select> </select>
@@ -400,11 +262,11 @@ class ConfigTab extends React.Component {
} }
} }
ConfigTab.propTypes = { UiTab.propTypes = {
user: PropTypes.shape({ user: PropTypes.shape({
name: PropTypes.string name: PropTypes.string
}), }),
dispatch: PropTypes.func dispatch: PropTypes.func
} }
export default CSSModules(ConfigTab, styles) export default CSSModules(UiTab, styles)

View File

@@ -1,7 +1,8 @@
import React, { PropTypes } from 'react' import React, { PropTypes } from 'react'
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import ConfigTab from './ConfigTab' import HotkeyTab from './HotkeyTab'
import UiTab from './UiTab'
import InfoTab from './InfoTab' import InfoTab from './InfoTab'
import StoragesTab from './StoragesTab' import StoragesTab from './StoragesTab'
import CSSModules from 'browser/lib/CSSModules' import CSSModules from 'browser/lib/CSSModules'
@@ -32,16 +33,27 @@ class Preferences extends React.Component {
} }
} }
handleEscButtonClick () {
this.props.close()
}
renderContent () { renderContent () {
const { boundingBox } = this.state const { boundingBox } = this.state
let { dispatch, config, data } = this.props let { dispatch, config, data } = this.props
switch (this.state.currentTab) { switch (this.state.currentTab) {
case 'INFO': case 'INFO':
return <InfoTab/> return <InfoTab />
case 'CONFIG': case 'HOTKEY':
return ( return (
<ConfigTab <HotkeyTab
dispatch={dispatch}
config={config}
/>
)
case 'UI':
return (
<UiTab
dispatch={dispatch} dispatch={dispatch}
config={config} config={config}
/> />
@@ -73,9 +85,10 @@ class Preferences extends React.Component {
let content = this.renderContent() let content = this.renderContent()
let tabs = [ let tabs = [
{target: 'STORAGES', label: 'Storages', icon: 'database'}, {target: 'STORAGES', label: 'Storages'},
{target: 'CONFIG', label: 'Config', icon: 'cogs'}, {target: 'HOTKEY', label: 'Hotkey'},
{target: 'INFO', label: 'Info', icon: 'info-circle'} {target: 'UI', label: 'UI'},
{target: 'INFO', label: 'Info'}
] ]
let navButtons = tabs.map((tab) => { let navButtons = tabs.map((tab) => {
@@ -88,9 +101,6 @@ class Preferences extends React.Component {
key={tab.target} key={tab.target}
onClick={(e) => this.handleNavButtonClick(tab.target)(e)} onClick={(e) => this.handleNavButtonClick(tab.target)(e)}
> >
<i styleName='nav-button-icon'
className={'fa fa-' + tab.icon}
/>
<span styleName='nav-button-label'> <span styleName='nav-button-label'>
{tab.label} {tab.label}
</span> </span>
@@ -104,6 +114,13 @@ class Preferences extends React.Component {
tabIndex='-1' tabIndex='-1'
onKeyDown={(e) => this.handleKeyDown(e)} onKeyDown={(e) => this.handleKeyDown(e)}
> >
<div styleName='top-bar'>
<p>Your menu for Boostnote</p>
</div>
<button styleName='top-bar-close' onClick={(e) => this.handleEscButtonClick(e)}>
<div styleName='top-bar-close-mark'>X</div>
<div styleName='top-bar-close-text'>esc</div>
</button>
<div styleName='nav'> <div styleName='nav'>
{navButtons} {navButtons}
</div> </div>

View File

@@ -8,15 +8,18 @@ $danger-lighten-color = lighten(#c9302c, 5%)
$statusBar-height = 24px $statusBar-height = 24px
$sideNav-width = 200px $sideNav-width = 200px
$sideNav--folded-width = 44px $sideNav--folded-width = 44px
$topBar-height = 50px $topBar-height = 60px
// UI default // UI default
$ui-text-color = #515151 $ui-text-color = #515151
$ui-inactive-text-color = #939395 $ui-inactive-text-color = #939395
$ui-borderColor = #D1D1D1 $ui-borderColor = #D1D1D1
$ui-backgroundColor = #FAFAFA $ui-backgroundColor = #FFFFFF
$ui-noteList-backgroundColor = #F3F3F3
$ui-noteDetail-backgroundColor = #F4F4F4
$ui-border = solid 1px $ui-borderColor $ui-border = solid 1px $ui-borderColor
$ui-active-color = #6AA5E9 $ui-active-color = #6AA5E9
$ui-tag-backgroundColor = rgba(0, 0, 0, 0.3)
// UI Button // UI Button
$ui-button-color = #939395 $ui-button-color = #939395
@@ -44,6 +47,9 @@ tooltip()
$ui-input--focus-borderColor = #369DCD $ui-input--focus-borderColor = #369DCD
$ui-input--disabled-backgroundColor = #DDD $ui-input--disabled-backgroundColor = #DDD
// Parts
$ui-favorite-star-button-color = #FFC216
/* /*
* # Border * # Border
*/ */
@@ -135,7 +141,10 @@ modal()
// Dark theme // Dark theme
$ui-dark-borderColor = lighten(#21252B, 20%) $ui-dark-borderColor = lighten(#21252B, 20%)
$ui-dark-backgroundColor = darken(#21252B, 10%) $ui-dark-backgroundColor = #1D1D1D
$ui-dark-noteList-backgroundColor = #181818
$ui-dark-noteDetail-backgroundColor = #0D0D0D
$ui-dark-tag-backgroundColor = rgba(255, 255, 255, 0.3)
$dark-background-color = lighten($ui-dark-backgroundColor, 10%) $dark-background-color = lighten($ui-dark-backgroundColor, 10%)
$ui-dark-text-color = #DDDDDD $ui-dark-text-color = #DDDDDD
$ui-dark-button--active-color = white $ui-dark-button--active-color = white

View File

@@ -41,7 +41,7 @@ By this, webpack will watch the code changes and apply it automatically.
We use Grunt. We use Grunt.
Acutal deploy can be run by `grunt`. However, you shouldn't use because the default task is including codesign and authenticode. Acutal deploy can be run by `grunt`. However, you shouldn't use because the default task is including codesign and authenticode.
So, we prepare a script which just make an excutable file. So, we prepare a script which just make an executable file.
``` ```
grunt pre-build grunt pre-build

View File

@@ -5,16 +5,16 @@ const packager = require('electron-packager')
const WIN = process.platform === 'win32' const WIN = process.platform === 'win32'
module.exports = function (grunt) { module.exports = function (grunt) {
var auth_code var authCode
try { try {
auth_code = grunt.file.readJSON('secret/auth_code.json') authCode = grunt.file.readJSON('secret/auth_code.json')
} catch (e) { } catch (e) {
if (e.origError.code === 'ENOENT') { if (e.origError.code === 'ENOENT') {
console.warn('secret/auth_code.json is not found. CodeSigning is not available.') console.warn('secret/auth_code.json is not found. CodeSigning is not available.')
} }
} }
const OSX_COMMON_NAME = auth_code != null ? auth_code.OSX_COMMON_NAME : '' const OSX_COMMON_NAME = authCode != null ? authCode.OSX_COMMON_NAME : ''
const WIN_CERT_PASSWORD = auth_code != null ? auth_code.WIN_CERT_PASSWORD : '' const WIN_CERT_PASSWORD = authCode != null ? authCode.WIN_CERT_PASSWORD : ''
var initConfig = { var initConfig = {
pkg: grunt.file.readJSON('package.json'), pkg: grunt.file.readJSON('package.json'),
@@ -98,7 +98,7 @@ module.exports = function (grunt) {
prune: true, prune: true,
overwrite: true, overwrite: true,
out: path.join(__dirname, 'dist'), out: path.join(__dirname, 'dist'),
ignore: /node_modules\/ace-builds\/(?!src-min)|node_modules\/ace-builds\/(?=src-min-noconflict)|node_modules\/devicon\/icons|dist|^\/browser|^\/secret|\.babelrc|\.gitignore|^\/\.gitmodules|^\/gruntfile|^\/readme.md|^\/webpack|^\/appdmg\.json|^\/node_modules\/grunt/ ignore: /node_modules\/ace-builds\/(?!src-min)|node_modules\/ace-builds\/(?=src-min-noconflict)|node_modules\/devicon\/icons|^\/browser|^\/secret|\.babelrc|\.gitignore|^\/\.gitmodules|^\/gruntfile|^\/readme.md|^\/webpack|^\/appdmg\.json|^\/node_modules\/grunt/
} }
switch (platform) { switch (platform) {
case 'win': case 'win':

View File

@@ -1,19 +1,10 @@
const electron = require('electron') const electron = require('electron')
const app = electron.app const app = electron.app
const Menu = electron.Menu
var finderWindow = null
app.on('ready', function () { app.on('ready', function () {
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
app.dock.hide() app.dock.hide()
} }
// var template = require('./finder-menu')
// var menu = Menu.buildFromTemplate(template)
// Menu.setApplicationMenu(menu)
finderWindow = require('./finder-window')
}) })
module.exports = app module.exports = app

View File

@@ -8,7 +8,6 @@
<link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css" media="screen" charset="utf-8"> <link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css" media="screen" charset="utf-8">
<link rel="stylesheet" href="../node_modules/highlight.js/styles/xcode.css" id="hljs-css">
<link rel="shortcut icon" href="favicon.ico"> <link rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" href="../node_modules/codemirror/lib/codemirror.css"> <link rel="stylesheet" href="../node_modules/codemirror/lib/codemirror.css">
@@ -32,23 +31,31 @@
<script src="../node_modules/codemirror/addon/mode/overlay.js"></script> <script src="../node_modules/codemirror/addon/mode/overlay.js"></script>
<script src="../node_modules/codemirror/addon/mode/loadmode.js"></script> <script src="../node_modules/codemirror/addon/mode/loadmode.js"></script>
<script src="../node_modules/codemirror/keymap/sublime.js"></script> <script src="../node_modules/codemirror/keymap/sublime.js"></script>
<script src="../node_modules/codemirror/keymap/vim.js"></script>
<script src="../node_modules/codemirror/addon/runmode/runmode.js"></script> <script src="../node_modules/codemirror/addon/runmode/runmode.js"></script>
<script src="../compiled/katex.js"></script> <script src="../node_modules/raphael/raphael.min.js"></script>
<script src="../compiled/react.js"></script> <script src="../node_modules/flowchart.js/release/flowchart.min.js"></script>
<script src="../compiled/react-dom.js"></script>
<script src="../compiled/redux.js"></script> <script src="../node_modules/katex/dist/katex.min.js"></script>
<script src="../compiled/react-redux.js"></script> <script src="../node_modules/react/dist/react.min.js"></script>
<script src="../node_modules/react-dom/dist/react-dom.min.js"></script>
<script src="../node_modules/redux/dist/redux.min.js"></script>
<script src="../node_modules/react-redux/dist/react-redux.min.js"></script>
<script>
window._ = require('lodash');
</script>
<script src="../node_modules/js-sequence-diagrams/fucknpm/sequence-diagram-min.js"></script>
<script> <script>
const electron = require('electron') const electron = require('electron')
electron.webFrame.setZoomLevelLimits(1, 1) electron.webFrame.setZoomLevelLimits(1, 1)
const _ = require('lodash') const _ = require('lodash')
var scriptUrl = _.find(electron.remote.process.argv, a => a === '--hot') var scriptUrl = _.find(electron.remote.process.argv, (a) => a === '--hot')
? 'http://localhost:8080/assets/finder.js' ? 'http://localhost:8080/assets/finder.js'
: '../compiled/finder.js' : '../compiled/finder.js'
var scriptEl=document.createElement('script') var scriptEl = document.createElement('script')
scriptEl.setAttribute("type","text/javascript") scriptEl.setAttribute('type', 'text/javascript')
scriptEl.setAttribute("src", scriptUrl) scriptEl.setAttribute('src', scriptUrl)
document.body.appendChild(scriptEl) document.body.appendChild(scriptEl)
</script> </script>
</body> </body>

View File

@@ -2,7 +2,6 @@ const electron = require('electron')
const app = electron.app const app = electron.app
const Menu = electron.Menu const Menu = electron.Menu
const ipc = electron.ipcMain const ipc = electron.ipcMain
const autoUpdater = electron.autoUpdater
const path = require('path') const path = require('path')
const ChildProcess = require('child_process') const ChildProcess = require('child_process')
const _ = require('lodash') const _ = require('lodash')
@@ -11,9 +10,8 @@ const GhReleases = require('electron-gh-releases')
var ipcServer = null var ipcServer = null
var mainWindow = null var mainWindow = null
var finderWindow = null
var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) { var shouldQuit = app.makeSingleInstance(function (commandLine, workingDirectory) {
if (mainWindow) { if (mainWindow) {
if (process.platform === 'win32') { if (process.platform === 'win32') {
mainWindow.minimize() mainWindow.minimize()
@@ -26,12 +24,8 @@ var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory)
if (shouldQuit) { if (shouldQuit) {
app.quit() app.quit()
return
} }
var version = app.getVersion()
var versionText = (version == null || version.length === 0) ? 'DEV version' : 'v' + version
var isUpdateReady = false var isUpdateReady = false
var ghReleasesOpts = { var ghReleasesOpts = {
@@ -108,14 +102,9 @@ app.on('ready', function () {
Menu.setApplicationMenu(menu) Menu.setApplicationMenu(menu)
break break
case 'win32': case 'win32':
finderWindow = require('./finder-window')
mainWindow.setMenu(menu) mainWindow.setMenu(menu)
break break
case 'linux': case 'linux':
// Finder is available on cinnamon only.
if (process.env.DESKTOP_SESSION === 'cinnamon') {
finderWindow = require('./finder-window')
}
Menu.setApplicationMenu(menu) Menu.setApplicationMenu(menu)
mainWindow.setMenu(menu) mainWindow.setMenu(menu)
} }

View File

@@ -54,7 +54,7 @@ var file = {
submenu: [ submenu: [
{ {
label: 'New Note', label: 'New Note',
accelerator: OSX ? 'Command + N' : 'Control + N', accelerator: 'CmdOrCtrl + N',
click: function () { click: function () {
mainWindow.webContents.send('top:new-note') mainWindow.webContents.send('top:new-note')
} }
@@ -125,20 +125,14 @@ var view = {
submenu: [ submenu: [
{ {
label: 'Reload', label: 'Reload',
accelerator: (function () { accelerator: 'CmdOrCtrl+R',
if (process.platform === 'darwin') return 'Command+R'
else return 'Ctrl+R'
})(),
click: function () { click: function () {
BrowserWindow.getFocusedWindow().reload() BrowserWindow.getFocusedWindow().reload()
} }
}, },
{ {
label: 'Toggle Developer Tools', label: 'Toggle Developer Tools',
accelerator: (function () { accelerator: OSX ? 'Command+Alt+I' : 'Ctrl+Shift+I',
if (process.platform === 'darwin') return 'Command+Alt+I'
else return 'Ctrl+Shift+I'
})(),
click: function () { click: function () {
BrowserWindow.getFocusedWindow().toggleDevTools() BrowserWindow.getFocusedWindow().toggleDevTools()
} }
@@ -175,7 +169,7 @@ var help = {
submenu: [ submenu: [
{ {
label: 'Boostnote official site', label: 'Boostnote official site',
click: function () { shell.openExternal('https://b00st.io/') } click: function () { shell.openExternal('https://boostnote.io/') }
}, },
{ {
label: 'Issue Tracker', label: 'Issue Tracker',

View File

@@ -2,12 +2,18 @@ const electron = require('electron')
const app = electron.app const app = electron.app
const BrowserWindow = electron.BrowserWindow const BrowserWindow = electron.BrowserWindow
const path = require('path') const path = require('path')
const Config = require('electron-config')
const config = new Config()
var mainWindow = new BrowserWindow({ var showMenu = process.platform !== 'win32'
width: 1080, let windowSize = config.get('windowsize') || { width: 1080, height: 720 }
height: 720,
minWidth: 420, let mainWindow = new BrowserWindow({
width: windowSize.width,
height: windowSize.height,
minWidth: 500,
minHeight: 320, minHeight: 320,
autoHideMenuBar: showMenu,
webPreferences: { webPreferences: {
zoomFactor: 1.0, zoomFactor: 1.0,
blinkFeatures: 'OverlayScrollbars' blinkFeatures: 'OverlayScrollbars'
@@ -43,6 +49,7 @@ if (process.platform !== 'linux' || process.env.DESKTOP_SESSION === 'cinnamon')
}) })
app.on('before-quit', function (e) { app.on('before-quit', function (e) {
config.set('windowsize', mainWindow.getBounds())
mainWindow.removeAllListeners() mainWindow.removeAllListeners()
}) })
} else { } else {

View File

@@ -5,7 +5,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css" media="screen" charset="utf-8"> <link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css" media="screen" charset="utf-8">
<link rel="stylesheet" href="../node_modules/highlight.js/styles/xcode.css" id="hljs-css">
<link rel="shortcut icon" href="../resources/favicon.ico"> <link rel="shortcut icon" href="../resources/favicon.ico">
<link rel="stylesheet" href="../node_modules/codemirror/lib/codemirror.css"> <link rel="stylesheet" href="../node_modules/codemirror/lib/codemirror.css">
<title>Boostnote</title> <title>Boostnote</title>
@@ -58,20 +57,27 @@
<script src="../node_modules/codemirror/addon/mode/overlay.js"></script> <script src="../node_modules/codemirror/addon/mode/overlay.js"></script>
<script src="../node_modules/codemirror/addon/mode/loadmode.js"></script> <script src="../node_modules/codemirror/addon/mode/loadmode.js"></script>
<script src="../node_modules/codemirror/keymap/sublime.js"></script> <script src="../node_modules/codemirror/keymap/sublime.js"></script>
<script src="../node_modules/codemirror/keymap/vim.js"></script>
<script src="../node_modules/codemirror/addon/runmode/runmode.js"></script> <script src="../node_modules/codemirror/addon/runmode/runmode.js"></script>
<script src="../node_modules/codemirror/addon/edit/continuelist.js"></script> <script src="../node_modules/codemirror/addon/edit/continuelist.js"></script>
<script src="../compiled/katex.js"></script> <script src="../node_modules/raphael/raphael.min.js"></script>
<script src="../compiled/react.js"></script> <script src="../node_modules/flowchart.js/release/flowchart.min.js"></script>
<script src="../compiled/react-dom.js"></script> <script>
<script src="../compiled/redux.js"></script> window._ = require('lodash')
<script src="../compiled/react-redux.js"></script> </script>
<script src="../node_modules/js-sequence-diagrams/fucknpm/sequence-diagram-min.js"></script>
<script src="../node_modules/katex/dist/katex.min.js"></script>
<script src="../node_modules/react/dist/react.min.js"></script>
<script src="../node_modules/react-dom/dist/react-dom.min.js"></script>
<script src="../node_modules/redux/dist/redux.min.js"></script>
<script src="../node_modules/react-redux/dist/react-redux.min.js"></script>
<script type='text/javascript'> <script type='text/javascript'>
const electron = require('electron') const electron = require('electron')
electron.webFrame.setZoomLevelLimits(1, 1) electron.webFrame.setZoomLevelLimits(1, 1)
const _ = require('lodash') var scriptUrl = window._.find(electron.remote.process.argv, (a) => a === '--hot')
var scriptUrl = _.find(electron.remote.process.argv, (a) => a === '--hot')
? 'http://localhost:8080/assets/main.js' ? 'http://localhost:8080/assets/main.js'
: '../compiled/main.js' : '../compiled/main.js'
var scriptEl = document.createElement('script') var scriptEl = document.createElement('script')

View File

@@ -1,11 +0,0 @@
{
"directory": "compiled",
"targets": {
"react": "https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.js",
"react-dom": "https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.js",
"redux": "https://cdnjs.cloudflare.com/ajax/libs/redux/3.5.2/redux.js",
"react-redux": "https://unpkg.com/react-redux@4.4.5/dist/react-redux.min.js",
"katex": "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.js",
"katex-style": "https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css"
}
}

View File

@@ -1,6 +1,6 @@
{ {
"name": "boost", "name": "boost",
"version": "0.7.0", "version": "0.8.1",
"description": "Boostnote", "description": "Boostnote",
"main": "index.js", "main": "index.js",
"license": "GPL-3.0", "license": "GPL-3.0",
@@ -8,10 +8,10 @@
"start": "electron ./index.js", "start": "electron ./index.js",
"hot": "electron ./index.js --hot", "hot": "electron ./index.js --hot",
"webpack": "webpack-dev-server --hot --inline --config webpack.config.js", "webpack": "webpack-dev-server --hot --inline --config webpack.config.js",
"postinstall": "npm run vendor",
"vendor": "oh-my-cdn",
"compile": "grunt compile", "compile": "grunt compile",
"test": "PWD=$(pwd) NODE_ENV=test ava" "test": "PWD=$(pwd) NODE_ENV=test ava",
"fix": "npm run lint --fix",
"lint": "eslint ./**/*.js"
}, },
"config": { "config": {
"electron-version": "1.2.8" "electron-version": "1.2.8"
@@ -36,20 +36,26 @@
"Romain Bazile (https://github.com/gromain)", "Romain Bazile (https://github.com/gromain)",
"Bruno Paz (https://github.com/brpaz)", "Bruno Paz (https://github.com/brpaz)",
"Fabian Mueller (https://github.com/dotcs)", "Fabian Mueller (https://github.com/dotcs)",
"Yoshihisa Mochihara (https://github.com/yosmoc)" "Yoshihisa Mochihara (https://github.com/yosmoc)",
"Mike Resoli (https://github.com/mikeres0)",
"tjado (https://github.com/tejado)",
"Sota Sugiura (https://github.com/sota1235)"
], ],
"bugs": { "bugs": {
"url": "https://github.com/BoostIO/Boostnote/issues" "url": "https://github.com/BoostIO/Boostnote/issues"
}, },
"homepage": "https://b00st.io", "homepage": "https://boostnote.io",
"dependencies": { "dependencies": {
"@rokt33r/markdown-it-math": "^4.0.1", "@rokt33r/markdown-it-math": "^4.0.1",
"@rokt33r/season": "^5.3.0", "@rokt33r/season": "^5.3.0",
"codemirror": "^5.19.0", "codemirror": "^5.19.0",
"electron-config": "^0.2.1",
"electron-gh-releases": "^2.0.2", "electron-gh-releases": "^2.0.2",
"flowchart.js": "^1.6.5",
"font-awesome": "^4.3.0", "font-awesome": "^4.3.0",
"highlight.js": "^9.3.0",
"immutable": "^3.8.1", "immutable": "^3.8.1",
"js-sequence-diagrams": "^1000000.0.6",
"katex": "^0.6.0",
"lodash": "^4.11.1", "lodash": "^4.11.1",
"markdown-it": "^6.0.1", "markdown-it": "^6.0.1",
"markdown-it-checkbox": "^1.1.0", "markdown-it-checkbox": "^1.1.0",
@@ -59,6 +65,11 @@
"mixpanel": "^0.4.1", "mixpanel": "^0.4.1",
"moment": "^2.10.3", "moment": "^2.10.3",
"node-ipc": "^8.1.0", "node-ipc": "^8.1.0",
"raphael": "^2.2.7",
"react": "^15.0.2",
"react-dom": "^15.0.2",
"react-redux": "^4.4.5",
"redux": "^3.5.2",
"sander": "^0.5.1", "sander": "^0.5.1",
"superagent": "^1.2.0", "superagent": "^1.2.0",
"superagent-promise": "^1.0.3" "superagent-promise": "^1.0.3"
@@ -78,6 +89,9 @@
"dom-storage": "^2.0.2", "dom-storage": "^2.0.2",
"electron-packager": "^6.0.0", "electron-packager": "^6.0.0",
"electron-prebuilt": "^1.2.8", "electron-prebuilt": "^1.2.8",
"eslint": "^3.13.1",
"eslint-config-standard": "^6.2.1",
"eslint-config-standard-jsx": "^3.2.0",
"faker": "^3.1.0", "faker": "^3.1.0",
"grunt": "^0.4.5", "grunt": "^0.4.5",
"grunt-electron-installer": "^1.2.0", "grunt-electron-installer": "^1.2.0",
@@ -85,7 +99,6 @@
"jsdom": "^9.4.2", "jsdom": "^9.4.2",
"merge-stream": "^1.0.0", "merge-stream": "^1.0.0",
"nib": "^1.1.0", "nib": "^1.1.0",
"oh-my-cdn": "^0.1.1",
"react": "^15.3.0", "react": "^15.3.0",
"react-color": "^2.2.2", "react-color": "^2.2.2",
"react-css-modules": "^3.7.6", "react-css-modules": "^3.7.6",
@@ -104,14 +117,9 @@
"grunt-electron-installer-debian": "^0.2.0" "grunt-electron-installer-debian": "^0.2.0"
}, },
"optional": false, "optional": false,
"standard": {
"globals": [
"localStorage"
]
},
"ava": { "ava": {
"files": [ "files": [
"tests/**/*.js" "tests/**/*-test.js"
], ],
"require": [ "require": [
"babel-register" "babel-register"

View File

@@ -1,37 +1,28 @@
# Boostnote # Boostnote
> [Boostnote store](#goods)をはじめました!! :tada: そして、[Pateron](https://www.patreon.com/boostnote)からも私達を支援することができます! > [Boostnote shop](https://boostnote.paintory.com/)をはじめました!! :tada:
そして、[Pateron](https://www.patreon.com/boostnote)からも私達を支援することができます!
![Boostnote app screenshot](https://cloud.githubusercontent.com/assets/5865853/18662404/3aa42396-7f55-11e6-88bf-f4ec6505ee8f.png) ![Boostnote app screenshot](./resources/repository/top.png)
![Boostnote app screenshot](https://cloud.githubusercontent.com/assets/5865853/18662139/f491adac-7f53-11e6-8631-2a447af9f36a.png)
オープンソースノートアプリ
次の用務がある場合にはIssue trackerを利用してください。 **ロードマップ・リクエスト一覧は[こちら](https://github.com/BoostIO/Boostnote/wiki/List-of-the-requested-features)です!**
皆さんからのプルリクをお待ちしています!
以下のような場合には、Issue trackerを利用してください。
- Boostnoteに関して質問したい時 - Boostnoteに関して質問したい時
- Boostnoteや計画事項にフィードバックがしたい時 - Boostnoteや計画事項にフィードバックがしたい時
- Boostnoteにバグを報告したい時 - Boostnoteにバグを報告したい時
- Boostnoteに寄与したい時
## Goal ## Goal
単に何かを書くのが楽しくなってしいです。 :grinning: 書くことが楽しくなってしいです。 :grinning:
- ターゲット OS : OSX, Windows, Linux(後々はモバイルも!) - ターゲット OS : OSX, Windows, Linux(後々はモバイルも!)
- Cloud : Google drive, Dropbox, One drive, iCloud... - Cloud : Google drive, Dropbox, One drive, iCloud...
- オープンソースで残ること! - オープンソースで残ること!
## 印象を受けたアプリ/サービス
- Atom
- Quiver
- Evernote
- GitKraken
- GitBook
- Gist
- Gistbox
- Snippets Lab
## Using stack ## Using stack
@@ -51,12 +42,12 @@
## Goods ## Goods
<img src="https://b00st.io/images/t3.png" width="250"/> <img src="https://boostnote.io/images/t3.png" width="250"/>
<img src="https://b00st.io/images/t1.png" width="250"/> <img src="https://boostnote.io/images/t1.png" width="250"/>
[Boostnote store](https://boostnote.paintory.com/)から幾つかのグッズを販売しています。 [Boostnote shop](https://boostnote.paintory.com/)から幾つかのグッズを販売しています。
商品は全世界何処でも届けることができます。このストアは[Paintory](https://paintory.com/)から提供されます 商品は全世界どこへでも届ける事が出来ます
## Donation ## Donation
@@ -64,18 +55,23 @@
## Author & Maintainer ## Author & Maintainer
[Rokt33r(Dick Choi of MAISIN&CO.)](https://github.com/rokt33r) - [Rokt33r](https://github.com/rokt33r)
- [sota1235](https://github.com/sota1235)
- [Kohei TAKATA](https://github.com/kohei-takata)
- [Kazu Yokomizo](https://github.com/kazup01)
## Contributors ## Contributors
- [Kazu Yokomizo](https://github.com/kazup01)
- [dojineko](https://github.com/dojineko) - [dojineko](https://github.com/dojineko)
- [Romain Bazile](https://github.com/gromain) - [Romain Bazile](https://github.com/gromain)
- [Bruno Paz](https://github.com/brpaz) - [Bruno Paz](https://github.com/brpaz)
- [Fabian Mueller](https://github.com/dotcs) - [Fabian Mueller](https://github.com/dotcs)
- [Yoshihisa Mochihara](https://github.com/yosmoc)
- [Mike Resoli](https://github.com/mikeres0)
- [tjado](https://github.com/tejado)
## Copyright & License ## Copyright & License
Copyright (C) 2016 MAISIN&CO. Copyright (C) 2017 Maisin&Co.
[GPL v3](./LICENSE). [GPL v3](./LICENSE).

View File

@@ -1,9 +1,8 @@
# Boostnote # Boostnote
> [Boostnote store](#goods)가 생겼습니다!! :tada: 그리고,[Pateron](https://www.patreon.com/boostnote)에서도 저희를 지원 하실 수 있습니다.! > [Boostnote store](https://boostnote.paintory.com/)가 생겼습니다!! :tada: 그리고,[Pateron](https://www.patreon.com/boostnote)에서도 저희를 지원 하실 수 있습니다.!
![Boostnote app screenshot](https://cloud.githubusercontent.com/assets/5865853/18662404/3aa42396-7f55-11e6-88bf-f4ec6505ee8f.png) ![Boostnote app screenshot](./resources/repository/top.png)
![Boostnote app screenshot](https://cloud.githubusercontent.com/assets/5865853/18662139/f491adac-7f53-11e6-8631-2a447af9f36a.png)
오픈소스 노트 앱 오픈소스 노트 앱
@@ -52,8 +51,8 @@
## Goods ## Goods
<img src="https://b00st.io/images/t3.png" width="250"/> <img src="https://boostnote.io/images/t3.png" width="250"/>
<img src="https://b00st.io/images/t1.png" width="250"/> <img src="https://boostnote.io/images/t1.png" width="250"/>
[Boostnote store](https://boostnote.paintory.com/)에서 몇가지 상품들을 팔고있습니다. [Boostnote store](https://boostnote.paintory.com/)에서 몇가지 상품들을 팔고있습니다.
@@ -74,6 +73,10 @@
- [Romain Bazile](https://github.com/gromain) - [Romain Bazile](https://github.com/gromain)
- [Bruno Paz](https://github.com/brpaz) - [Bruno Paz](https://github.com/brpaz)
- [Fabian Mueller](https://github.com/dotcs) - [Fabian Mueller](https://github.com/dotcs)
- [Yoshihisa Mochihara](https://github.com/yosmoc)
- [Mike Resoli](https://github.com/mikeres0)
- [tjado](https://github.com/tejado)
- [sota1235](https://github.com/sota1235)
## Copyright & License ## Copyright & License

102
readme.md
View File

@@ -1,88 +1,36 @@
# Boostnote <h1 align="center">
<a href="https://github.com/BoostIO/Boostnote"><img src="./resources/app.png" alt="Boostnote" width="180"></a>
<br>
Boostnote
<br>
<br>
</h1>
<h4 align="center">Note-taking app for programmers. </h4>
<h5 align="center">macOS, Windows and Linux</h5>
<h5 align="center">Built with Electron, React + Redux, Webpack and CSSModules</h5>
> We launched [Boostnote store](#goods)!! :tada: Also, you can support us from [Patreon](https://www.patreon.com/boostnote)! ![Boostnote app screenshot](./resources/repository/top.png)
![Boostnote app screenshot](https://cloud.githubusercontent.com/assets/5865853/18662404/3aa42396-7f55-11e6-88bf-f4ec6505ee8f.png) [![Build Status](https://travis-ci.org/BoostIO/Boostnote.svg?branch=master)](https://travis-ci.org/BoostIO/Boostnote)
![Boostnote app screenshot](https://cloud.githubusercontent.com/assets/5865853/18662139/f491adac-7f53-11e6-8631-2a447af9f36a.png)
Simple opensource note app for developer.
You can use the issue tracker of this repository for
- asking a question about Boostnote
- giving a feedback about Boostnote and its future plan
- reporting a bug of Boostnote
- wanting to contribute Boostnote
We have a slack if you want to engage us deeply, ask @rokt33r to join.
- [日本語](./readme-ja.md)
- [한국어](./readme-ko.md)
## Goal
We just want you to enjoying writing anything. :grinning:
- Target OS : OSX, Windows, Linux(also mobile somewhen!)
- Cloud : Google drive, Dropbox, One drive, iCloud...
- Remaining opensource forever!
Check planned features [here](https://github.com/BoostIO/Boostnote/issues/68)!
## Inspired by
- Atom
- Quiver
- Evernote
- GitKraken
- GitBook
- Gist
- Gistbox
- Snippets Lab
## Using stack
- Electron
- React
- Webpack
- Redux
- CSSModules
## Codestyle
[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)
## Development
- [Build](docs/build.md)
## Goods
<img src="https://b00st.io/images/t3.png" width="250"/>
<img src="https://b00st.io/images/t1.png" width="250"/>
We're currently selling some goods from [Boostnote store](https://boostnote.paintory.com/).
The product can be sent anywhere in the world. This store is powered by [Paintory](https://paintory.com/)
## Donation
We launched a [Patreon page](https://www.patreon.com/boostnote).
## Author & Maintainer ## Author & Maintainer
- [Rokt33r](https://github.com/rokt33r)
[Rokt33r(Dick Choi of MAISIN&CO.)](https://github.com/rokt33r) - [sota1235](https://github.com/sota1235)
- [Kohei TAKATA](https://github.com/kohei-takata)
- [Kazu Yokomizo](https://github.com/kazup01)
## Contributors ## Contributors
[Great contributors](https://github.com/BoostIO/Boostnote/graphs/contributors) :tada:
- [Kazu Yokomizo](https://github.com/kazup01)
- [dojineko](https://github.com/dojineko)
- [Romain Bazile](https://github.com/gromain)
- [Bruno Paz](https://github.com/brpaz)
- [Fabian Mueller](https://github.com/dotcs)
- [Yoshihisa Mochihara](https://github.com/yosmoc)
## Copyright & License ## More Information
* Website: http://boostnote.io/
* Roadmap(upcoming features and bug fixes): https://goo.gl/Mdu44q
* Boostnote Shop(Products are shipped to all over the world :+1:): https://boostnote.paintory.com/
* Donation: [Patreon](https://www.patreon.com/boostnote)
* Development: https://github.com/BoostIO/Boostnote/blob/master/docs/build.md
* Copyright (C) 2017 Maisin&Co.
Copyright (C) 2016 MAISIN&CO. ## License
[GPL v3](./LICENSE). [GPL v3](./LICENSE).

BIN
resources/app.icns Normal file → Executable file

Binary file not shown.

BIN
resources/app.ico Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

After

Width:  |  Height:  |  Size: 361 KiB

BIN
resources/app.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 36 KiB

BIN
resources/boostnote-install.gif Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 12 KiB

BIN
resources/boostnote-install.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 30 KiB

BIN
resources/boostnote-install@2x.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 71 KiB

BIN
resources/dmg.icns Normal file → Executable file

Binary file not shown.

BIN
resources/dmg.ico Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

After

Width:  |  Height:  |  Size: 361 KiB

BIN
resources/dmg.png Normal file → Executable file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Some files were not shown because too many files have changed in this diff Show More