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

Compare commits

...

705 Commits

Author SHA1 Message Date
Kohei TAKATA
bfd67fb7f1 Merge pull request #735 from BoostIO/feature-v0-8-12
v0.8.12
2017-07-29 15:04:53 +09:00
Kohei TAKATA
e6bd6a5077 v0.8.12 2017-07-29 13:58:11 +09:00
Kohei TAKATA
350af844ca Merge pull request #736 from BoostIO/fix-layout
Fix layout
2017-07-29 13:56:21 +09:00
Kazu Yokomizo
a49d53179a Change “Trashed” to “Trash” 2017-07-29 13:49:45 +09:00
Kazu Yokomizo
e68069fd2f Fix undo button layout at notedetail 2017-07-29 13:40:04 +09:00
SuenagaRyota
a193ba3e6c Merge pull request #732 from asmsuechan/fix-image-path-on-dropped
Make it work on windows
2017-07-26 15:55:30 +09:00
asmsuechan
9034b3ab54 Make it work on windows 2017-07-26 15:47:38 +09:00
SuenagaRyota
e86464535d Merge pull request #730 from asmsuechan/make-image-path-relative
Make image path relative
2017-07-26 14:33:41 +09:00
asmsuechan
e8553caa65 Make finder work fine 2017-07-26 14:29:55 +09:00
asmsuechan
044e6b7180 Make image path relative 2017-07-26 13:16:32 +09:00
SuenagaRyota
0266770657 Merge pull request #726 from asmsuechan/fix-default-font-on-windows
iss #155 Change defaut font on windows_
2017-07-25 16:04:12 +09:00
SuenagaRyota
2d6f7c08e8 Merge pull request #728 from asmsuechan/iss-727
iss #727 fix incorrect encoding in link
2017-07-25 15:59:28 +09:00
asmsuechan
0a27819a7f iss #727 fix incorrect encoding in link 2017-07-25 15:35:44 +09:00
SuenagaRyota
3185c25ee1 Merge pull request #724 from BoostIO/fix-button-at-markdown-eidt
Fix hidden button
2017-07-25 14:32:37 +09:00
asmsuechan
820802cdc2 iss #155 Change defaut font on windows_ 2017-07-25 14:04:39 +09:00
Kazu Yokomizo
2c169e6f15 Merge pull request #723 from asmsuechan/fix-typo-for-info-data-collection
Fix typo in InfoTab
2017-07-25 13:45:23 +09:00
Kazu Yokomizo
49be1320f9 Fix hidden button 2017-07-25 13:44:17 +09:00
asmsuechan
6bc4ecce48 Fix typo in InfoTab 2017-07-25 11:57:04 +09:00
SuenagaRyota
0290d23832 Merge pull request #722 from BoostIO/fix-layout
Fix layout
2017-07-25 10:18:12 +09:00
Kazu Yokomizo
e001c97e01 Make padding between Storages at SideNav. 2017-07-24 19:18:48 +09:00
Kazu Yokomizo
976d1bb4f3 Delete unnecessary comma. 2017-07-24 19:09:13 +09:00
Kazu Yokomizo
dee6495b08 Fix typo 2017-07-24 18:12:33 +09:00
Kazu Yokomizo
4a77f250f1 Fix button layout 2017-07-24 17:55:47 +09:00
Kazu Yokomizo
c697f19642 Fix layout at export note in InfoPanel 2017-07-24 17:00:08 +09:00
Kazu Yokomizo
f7d1f9e949 Fix InfoTab layout 2017-07-24 14:47:10 +09:00
Kazu Yokomizo
27b9952f8e Change policy content 2017-07-24 14:39:43 +09:00
Kazu Yokomizo
961dab4a97 Merge pull request #721 from BoostIO/udpate-slack-link
Update readme
2017-07-24 12:11:56 +09:00
Kazu Yokomizo
930b6bc927 Update readme
Update the slack link.
2017-07-24 11:53:39 +09:00
SuenagaRyota
ed7d8258cf Merge pull request #720 from asmsuechan/goodby-ctrl-g
Goodbye Ctrl-G
2017-07-22 16:44:48 +09:00
asmsuechan
762425125f Remove Ctrl-G because it's unneccessary and conflicts with CodeMirror 2017-07-22 16:41:08 +09:00
SuenagaRyota
03bdf0c653 Merge pull request #719 from asmsuechan/fix-inseration-image
Fix inseration position
2017-07-22 16:13:25 +09:00
asmsuechan
7002026190 Fix inseration position 2017-07-22 16:05:14 +09:00
SuenagaRyota
b35395e6bd Merge pull request #709 from asmsuechan/add-exports-to-infoPanel
Add exports to infoPanel
2017-07-22 15:47:01 +09:00
SuenagaRyota
b74fb76d03 Merge pull request #718 from asmsuechan/fix-typos
Fix typos Dynamit to Dynamic
2017-07-22 15:42:49 +09:00
asmsuechan
72d2df465b Fix typos Dynamit to Dynamic 2017-07-22 15:33:56 +09:00
SuenagaRyota
2592c943f7 Merge pull request #717 from asmsuechan/fix-a-bug-on-click
Fix a bug on click
2017-07-22 15:28:38 +09:00
asmsuechan
7b3a3ba200 Fix by eslint 2017-07-22 15:24:51 +09:00
asmsuechan
8369832585 Fix a bug on click 2017-07-22 15:11:59 +09:00
SuenagaRyota
d94a674343 Merge pull request #716 from asmsuechan/change-note-link-content
Change ["title"](note-hash) to [the exact title](note-hash)
2017-07-22 15:01:04 +09:00
SuenagaRyota
260611ffd6 Merge pull request #715 from asmsuechan/add-checkbox-for-ama
Add checkbox for ama
2017-07-22 14:57:31 +09:00
asmsuechan
690549b57f Change a word 2017-07-22 14:34:28 +09:00
asmsuechan
5d9aeb4c04 Fix typo 2017-07-22 14:32:18 +09:00
asmsuechan
eddfdea2ca Fix a closing tag and a condition 2017-07-22 14:20:42 +09:00
asmsuechan
a40385f87f Add policy 2017-07-22 13:58:02 +09:00
asmsuechan
0123526c98 Change ["title"](note-hash) to [the exact title](note-hash) 2017-07-22 11:29:39 +09:00
asmsuechan
275e3317a3 Add checkbox for ama 2017-07-22 08:59:27 +09:00
SuenagaRyota
d0b835a825 Merge pull request #710 from asmsuechan/fix-image-dropped
Change to create a new directory when storage/images does not exist
2017-07-16 15:52:03 +09:00
asmsuechan
f450260ff8 Fix a prop name noteKey to noteLink 2017-07-16 15:16:59 +09:00
asmsuechan
5f7b119e5c Remove an useless 'cancel' button 2017-07-16 15:06:22 +09:00
asmsuechan
bb9eb494e9 Change to create a new directory when storage/images does not exist 2017-07-16 15:02:18 +09:00
asmsuechan
6ea2b5e1d9 Add exports to infoPanel 2017-07-15 19:33:58 +09:00
SuenagaRyota
b21baf1ce5 Merge pull request #708 from asmsuechan/change-note-hash
Change noteHash to noteLink in the input in InfoPanel
2017-07-15 16:57:55 +09:00
SuenagaRyota
4c3fd461e4 Merge pull request #707 from asmsuechan/remove-dialogbox-from-trash
Remove a dialogbox from onTrashButtonClick
2017-07-15 14:47:38 +09:00
asmsuechan
8365a60d5d Change noteHash to noteLink in the input in InfoPanel 2017-07-15 13:41:22 +09:00
asmsuechan
804ac1aa96 Remove a dialogbox from onTrashButtonClick 2017-07-15 12:52:55 +09:00
SuenagaRyota
49fd2cfc4d Merge pull request #706 from asmsuechan/change-shotrcut-ctrl-u-to-ctrl-k
Change the keymap of Ctrl-U to Ctrl-K
2017-07-15 12:51:40 +09:00
asmsuechan
2bb2a52f27 Change the keymap of Ctrl-U to Ctrl-K 2017-07-14 18:18:38 +09:00
Kazu Yokomizo
8d71b28afa Merge pull request #705 from BoostIO/udpate-readme
Fix slack link
2017-07-13 16:23:34 +09:00
Kazu Yokomizo
86eac7054d Update Readmd 2017-07-13 15:41:56 +09:00
SuenagaRyota
dccb92d72b Merge pull request #297 from asmsuechan/add-trash-can
Add trash can
2017-07-12 15:53:49 +09:00
asmsuechan
2e628de9c6 Restore missing components 2017-07-12 15:48:11 +09:00
asmsuechan
2d243abc12 Add condition 2017-07-12 15:48:11 +09:00
asmsuechan
ae08bf4d7a Escape from addition a note when the note is in the trashbox 2017-07-12 15:48:11 +09:00
asmsuechan
cbff5fb585 Fix indents pointed by lint 2017-07-12 15:48:11 +09:00
asmsuechan
2650cc2f1c Add trash can 2017-07-12 15:48:08 +09:00
Kazu Yokomizo
ec560ceab1 Merge pull request #702 from BoostIO/update-readme
Update Readme
2017-07-11 01:01:19 +09:00
Kazu Yokomizo
ad17cb8837 Update Readme 2017-07-11 00:55:21 +09:00
Kazu Yokomizo
4f98d9641a Merge pull request #698 from BoostIO/update-layout
Update layout
2017-07-11 00:20:59 +09:00
Kazu Yokomizo
17535ccd4c Add Info Panel at SnippetDetail 2017-07-10 17:43:20 +09:00
Kazu Yokomizo
110c1ea337 Delete update date at under of NoteDetail 2017-07-10 17:13:18 +09:00
Kazu Yokomizo
7e087bfbab Fix info panel layout 2017-07-10 17:07:44 +09:00
SuenagaRyota
85e0d4b922 Merge pull request #697 from asmsuechan/remove-sharp-from-hash
Remove sharp from note hash on list:jump
2017-07-10 16:43:02 +09:00
asmsuechan
265262ccbf Remove sharp from note hash on list:jump 2017-07-10 16:37:07 +09:00
Kazu Yokomizo
345008e9b6 Fix info area layout at NoteDetail 2017-07-10 16:28:50 +09:00
SuenagaRyota
849aa05d76 Merge pull request #696 from asmsuechan/replace-cm-searchbox-to-official-search-addon
Replace cm searchbox to official search addon
2017-07-10 14:21:47 +09:00
asmsuechan
5ff5ec6a71 Remove cm-searchbox 2017-07-09 22:47:15 +09:00
asmsuechan
684c3f64aa Add search addon 2017-07-09 22:46:23 +09:00
SuenagaRyota
4ff73ede59 Merge pull request #695 from asmsuechan/bugfix-on-click-event
Fix an error on click event
2017-07-09 18:20:51 +09:00
asmsuechan
7302d83f60 Fix a bug on click event 2017-07-09 18:08:33 +09:00
SuenagaRyota
f9836fd66e Merge pull request #692 from asmsuechan/add-info-button
Add info button
2017-07-09 17:16:06 +09:00
SuenagaRyota
c0f05695fe Merge pull request #686 from asmsuechan/add-search-box
Add search-box
2017-07-09 17:15:57 +09:00
SuenagaRyota
e50a1172d6 Merge pull request #693 from asmsuechan/feature-links-among-notes
Feature links among notes
2017-07-09 17:15:50 +09:00
Kazu Yokomizo
7a4234e73c Merge pull request #690 from BoostIO/update-layout
Fix layout
2017-07-09 13:29:00 +09:00
Kazu Yokomizo
4b9640e5a3 Fix star position at NoteList 2017-07-09 12:56:02 +09:00
Kazu Yokomizo
4b58054100 Fix tag area layout at NoteItem 2017-07-09 12:46:46 +09:00
Kazu Yokomizo
8951dbf4ed Fix star position at NoteList 2017-07-08 16:05:45 +09:00
Kazu Yokomizo
5047bc94eb Fix search area layout 2017-07-08 15:58:40 +09:00
asmsuechan
75fb29c594 Change == to === 2017-07-08 15:44:20 +09:00
asmsuechan
bd75f7fd2c Remove a display of a note hash 2017-07-08 14:08:28 +09:00
asmsuechan
8b8cb3c9b4 Change styleName in each styles 2017-07-08 14:08:28 +09:00
asmsuechan
b479b21c37 Remove a blank line 2017-07-08 14:08:28 +09:00
asmsuechan
525c490704 Remove console.log 2017-07-08 14:08:28 +09:00
asmsuechan
2e3599d005 Add a feature which enables to link between notes 2017-07-08 14:08:28 +09:00
asmsuechan
f005bb1e46 hoge 2017-07-08 14:02:03 +09:00
asmsuechan
21f96febdb Fix some pointed by lint 2017-07-08 13:37:24 +09:00
asmsuechan
805829be78 Make InfoButton component stateless 2017-07-08 13:32:37 +09:00
asmsuechan
a7bd3f253f Rename getLastUpdated() to formatDate() 2017-07-08 13:16:19 +09:00
asmsuechan
81e8a290f0 Add infomation panel 2017-07-08 13:16:02 +09:00
Kazu Yokomizo
f46a967b6e Fix an error 2017-07-08 12:31:21 +09:00
Kazu Yokomizo
b78d9534aa Fix layout 2017-07-08 02:18:33 +09:00
SuenagaRyota
bdefaf7427 Merge pull request #681 from BoostIO/edit-initial-files
Edit initial files
2017-07-07 20:59:50 +09:00
SuenagaRyota
43550c7dec Merge pull request #688 from asmsuechan/remove-handle-note-context-menu
Remove the context menu for deletion
2017-07-07 20:12:11 +09:00
asmsuechan
1b07d393f2 Rename handleDeleteButtonClick to handleTrashButtonClick 2017-07-07 20:04:47 +09:00
asmsuechan
44fc356775 Remove the context menu for deletion 2017-07-07 19:45:02 +09:00
SuenagaRyota
5623c68170 Merge pull request #684 from BoostIO/change-menu-to-preferences
Change “Menu” to “Preferences”, and icon.
2017-07-07 18:11:01 +09:00
asmsuechan
d5f82943cf Edit style 2017-07-07 18:06:08 +09:00
asmsuechan
96a020341d Add search-box 2017-07-07 17:59:01 +09:00
Kazu Yokomizo
99b5f75763 Change “Menu” to “Preferences”, and icon. 2017-07-06 14:27:18 +09:00
SuenagaRyota
a128ff7cd8 Merge pull request #683 from asmsuechan/add-iss_template.md
Add issue template
2017-07-06 13:53:26 +09:00
Kazu Yokomizo
59329cc5da Fix typo 2017-07-06 13:50:39 +09:00
asmsuechan
ecd5daaf55 Add issue template 2017-07-06 13:44:19 +09:00
Kazu Yokomizo
514232d720 Merge pull request #682 from BoostIO/update-slack-link
Update slack link
2017-07-06 13:29:39 +09:00
Kazu Yokomizo
93abfe3202 Update slack link 2017-07-06 13:23:22 +09:00
Kazu Yokomizo
4d9e0e3bd7 Change default theme at editor and code-block 2017-07-06 02:32:14 +09:00
Kazu Yokomizo
75d9bf8e38 Edit initial files 2017-07-06 02:31:41 +09:00
SuenagaRyota
ccb9752254 Merge pull request #678 from asmsuechan/remove-e2e-document
Remove e2e documents
2017-07-05 13:38:42 +09:00
asmsuechan
0f2ca19c6c Remove the script of e2e test 2017-07-05 13:33:07 +09:00
asmsuechan
d5a77aade4 Remove testing.md 2017-07-05 13:32:06 +09:00
SuenagaRyota
3c89e6a128 Merge pull request #672 from asmsuechan/componentnize-top-bar-of-note-detail
Componentnize TrashButton
2017-07-02 22:29:14 +09:00
SuenagaRyota
a36be79977 Merge pull request #667 from asmsuechan/randomize-image-name
Randomize the image name when it's dropped
2017-07-02 22:22:23 +09:00
asmsuechan
617f0e0f9c Remove duplicated styles 2017-07-02 22:13:35 +09:00
asmsuechan
0db1a94105 Replace a button to TrashButton component 2017-07-02 22:13:35 +09:00
asmsuechan
f29f97a00f Add TrashButton component 2017-07-02 22:13:32 +09:00
asmsuechan
032b5a59f2 Remove encodeURI 2017-07-01 18:07:16 +09:00
SuenagaRyota
1e5bc395ac Merge pull request #671 from asmsuechan/goodbye-spectron
Goodbye spectron
2017-07-01 12:43:06 +09:00
asmsuechan
fef4afe660 Change .travis.yml 2017-07-01 12:02:52 +09:00
asmsuechan
679ed1eacf Remove e2e tests 2017-07-01 12:02:52 +09:00
asmsuechan
78a9320017 Remove spectron 2017-07-01 12:01:16 +09:00
asmsuechan
927981bf30 Randomize the image name when it's dropped 2017-06-28 13:05:40 +09:00
Kazu Yokomizo
70ea2f6c14 Merge pull request #665 from BoostIO/update-slack-link
Update slack link
2017-06-27 13:46:57 +09:00
Kazu Yokomizo
a6779414ff Delete readme.ja 2017-06-27 13:34:25 +09:00
Kazu Yokomizo
b62fcf523a Update slack link 2017-06-27 13:33:48 +09:00
Kazu Yokomizo
d0bbea5a97 Merge pull request #664 from asmsuechan/auth-aws-only-production
Exclude auth of aws only production
2017-06-26 15:38:33 +09:00
asmsuechan
212d7027fc Exclude auth of aws only production 2017-06-26 15:33:58 +09:00
Kohei TAKATA
be1a5b09da Merge pull request #663 from BoostIO/feature-v0-8-11
v0.8.11
2017-06-24 13:28:49 +09:00
Kohei TAKATA
3de2db4459 v0.8.11 2017-06-24 10:38:13 +09:00
Kazu Yokomizo
f2405a5b34 Merge pull request #661 from BoostIO/translate-to-russian
Add Russian files
2017-06-23 00:51:26 +09:00
Kazu Yokomizo
94abb8f959 Add credit 2017-06-22 23:38:23 +09:00
Kazu Yokomizo
2e30db05bc Add credit 2017-06-22 23:38:05 +09:00
Kazu Yokomizo
c93f3cc5dd Add credit 2017-06-22 23:37:14 +09:00
Kazu Yokomizo
068f8f2ba9 Update contributing.md 2017-06-22 23:35:27 +09:00
Kazu Yokomizo
0980c3b012 Add Russian files 2017-06-22 23:29:45 +09:00
SuenagaRyota
5288d6768f Merge pull request #658 from BoostIO/fix-scroll-bar-z-index
Fix not to show scroll bar when full screen mode in Windows
2017-06-22 14:42:46 +09:00
Kohei TAKATA
34491f4ea4 Remove unnecessary style 2017-06-21 22:53:22 +09:00
Kohei TAKATA
8c73ca8854 Fix not to show scroll bar when full screen mode in Windows 2017-06-21 22:51:21 +09:00
Kazu Yokomizo
0786d8eab6 Merge pull request #656 from BoostIO/add-backers-file
Add backers.md
2017-06-21 20:05:59 +09:00
Kazu Yokomizo
209518c815 Add backers.md 2017-06-21 19:42:51 +09:00
SuenagaRyota
b2753b6457 Merge pull request #644 from BoostIO/windows-fullscreen-zIndex
Fixed z-index at NoteDetail when fullscreen mode in windows.
2017-06-21 09:31:33 +09:00
Kazu Yokomizo
4775a920c0 Merge pull request #653 from BoostIO/update-slack-link
Update slack link
2017-06-20 21:51:01 +09:00
Kazu Yokomizo
0e94dc8740 Update slack link 2017-06-20 21:40:41 +09:00
Kazu Yokomizo
cf68d202d5 Update slack linl 2017-06-20 21:40:11 +09:00
SuenagaRyota
d29ba2bf16 Merge pull request #647 from clone1612/productionSizeFix
Fix dependency type of Spectron module
2017-06-18 14:39:31 +09:00
Kazu Yokomizo
720686cef5 Merge pull request #649 from asmsuechan/add-copy-on-ctrl-c-on-vim
Make Ctrl-C copy
2017-06-18 14:31:35 +09:00
asmsuechan
0625c65cf0 Make Ctrl-C copy 2017-06-18 08:14:33 +09:00
Jannick Hemelhof
acaefe22d1 Fix dependency type of spectron module 2017-06-17 18:01:01 +02:00
Kazu Yokomizo
df1f083ebf Merge pull request #645 from AlbertHilb/FixTypo
Rename `TodolistPercentage.js` to `TodoListPercentage.js`.
2017-06-17 22:25:28 +09:00
Raffaele De Feo
5a1dfc2ca9 Rename TodolistPercentage.js to TodoListPercentage.js. 2017-06-17 14:42:40 +02:00
Kazu Yokomizo
d84894f1bf Merge pull request #643 from BoostIO/update-fullscreen-btn-position
Change fullscreen button position at NoteDetail
2017-06-16 22:35:56 +09:00
SuenagaRyota
0fdc444c4c Merge pull request #642 from BoostIO/fix-analytics
Fix initialize logic of analytics
2017-06-16 22:35:33 +09:00
Kazu Yokomizo
4d216c6f13 Fixed z-index at NoteDetail when fullscreen mode in windows. 2017-06-16 22:25:48 +09:00
Kazu Yokomizo
1c0af8eede Change fullscreen button position at NoteDetail 2017-06-16 21:58:02 +09:00
Kohei TAKATA
f443f9264a Fix initialize logic of analytics 2017-06-16 21:35:21 +09:00
SuenagaRyota
d9b2981327 Merge pull request #325 from asmsuechan/feature-import-from-md-file
Add importer which imports files from .md/.txt
2017-06-16 21:28:04 +09:00
asmsuechan
68e36d2a6d Fix some pointed by lint 2017-06-16 21:17:39 +09:00
SuenagaRyota
68b91bf98c Merge pull request #611 from asmsuechan/error-handling-for-loading-notes
Fix errorhandling on cases of invalid notes
2017-06-16 21:09:48 +09:00
Kazu Yokomizo
b91ddfad05 Merge pull request #640 from BoostIO/update-slack-link
Update slack link
2017-06-13 11:44:21 +09:00
Kazu Yokomizo
a110cbfb5d Update slack link 2017-06-13 11:38:57 +09:00
Kazu Yokomizo
d69f45b0c9 Update slack link 2017-06-13 11:38:22 +09:00
asmsuechan
07df26d5c4 Change to use findNoteTitle() 2017-06-13 11:13:07 +09:00
asmsuechan
d24bcb7f86 Change to template literal 2017-06-13 11:06:09 +09:00
asmsuechan
9f383ba491 Add an option to enable selectiong multiple files 2017-06-13 11:06:09 +09:00
asmsuechan
c38a76d587 Add importer which imports files from .md/.txt 2017-06-13 11:06:00 +09:00
SuenagaRyota
994ca5dd02 Merge pull request #639 from hassec/FixAWSInclude
Fix typo in includes
2017-06-13 10:24:56 +09:00
Christoph Hasse
9281f8f6cb fix spelling to avoid include error 2017-06-13 00:59:37 +02:00
Kohei TAKATA
324f579474 Merge pull request #636 from BoostIO/feature-v0-8-10
v0.8.10
2017-06-13 02:52:07 +09:00
Kohei TAKATA
10bd2d4547 v0.8.10 2017-06-12 22:44:28 +09:00
SuenagaRyota
d1942868e4 Merge pull request #635 from asmsuechan/add-notification-on-copying-a-codeblock
Add notification on a copy button clicked
2017-06-12 21:54:56 +09:00
asmsuechan
a409b3e48d Add notification on a copy button clicked 2017-06-12 21:44:29 +09:00
SuenagaRyota
21004aab6a Merge pull request #634 from asmsuechan/enable-analytics-on-develop
Disable awsAnalytics on develop
2017-06-12 19:07:32 +09:00
asmsuechan
eaf88c6491 Disable awsAnalytics on develop 2017-06-12 18:57:40 +09:00
SuenagaRyota
17dcd1b6f1 Merge pull request #633 from asmsuechan/iss-619
Fix a rendering bug
2017-06-12 18:44:40 +09:00
asmsuechan
244a06eea6 Fix some pointed by lint 2017-06-12 18:12:11 +09:00
asmsuechan
afb13af7a1 iss #619 Add a test for teh helper methods 2017-06-12 18:05:32 +09:00
asmsuechan
ff9b935e98 iss #619 Add an entity to fix the rendering bug 2017-06-12 18:01:04 +09:00
SuenagaRyota
4250d6fe52 Merge pull request #632 from asmsuechan/handling-pull-602
Handling pull 602
2017-06-12 17:43:42 +09:00
SuenagaRyota
5bc2094f10 Merge pull request #628 from BoostIO/feature-improve-search-textbox-ux
improve searchTextBox UX
2017-06-12 17:41:27 +09:00
Kevin Nadro
552653c0ed for got run eslint 2017-06-12 17:34:14 +09:00
Kevin Nadro
c9bbc61c95 cleaning up code and fixing slider bug on fullscreen mode 2017-06-12 17:34:08 +09:00
Kevin Nadro
41a04aa3f1 reworking architecture of code 2017-06-12 17:34:02 +09:00
Kevin Nadro
cd421c4662 fixed the state change and cleaned up code for eslint 2017-06-12 17:33:56 +09:00
Kevin Nadro
063e2e02bd fixing some code from the comments 2017-06-12 17:33:50 +09:00
Kevin Nadro
0c3019b52e added fullscreen button for notes and snippets
allows user to hide the sidebars for fullscreen editing
2017-06-12 17:33:44 +09:00
Kevin Nadro
2ee2494dc4 for got run eslint 2017-06-12 17:33:37 +09:00
Kevin Nadro
df6ff1fffe cleaning up code and fixing slider bug on fullscreen mode 2017-06-12 17:33:31 +09:00
Kevin Nadro
0d2e6a6a12 forgot this in last commit 2017-06-12 17:33:24 +09:00
Kevin Nadro
79ed55a76f reworking architecture of code 2017-06-12 17:32:59 +09:00
Kevin Nadro
cbe58b9437 fixed the state change and cleaned up code for eslint 2017-06-12 17:30:38 +09:00
Kevin Nadro
afc729b1c3 fixing some code from the comments 2017-06-12 17:30:29 +09:00
Kevin Nadro
5d0cb0302e added fullscreen button for notes and snippets
allows user to hide the sidebars for fullscreen editing
2017-06-12 17:30:19 +09:00
Sosuke Suzuki
29e0d121cd improve searchTextBox ux 2017-06-11 15:42:07 +09:00
Kohei TAKATA
48ca13f82c Merge pull request #620 from BoostIO/feature-AmazonMobileAnalytics
Feature amazon mobile analytics
2017-06-10 13:45:38 +09:00
Sosuke Suzuki
278061e4f1 fix spacing 2017-06-10 12:58:24 +09:00
Sosuke Suzuki
186a815821 config to use dynamic customEvents 2017-06-10 12:51:01 +09:00
Sosuke Suzuki
2fea9eb874 setting AMA custom events 2017-06-10 12:50:19 +09:00
Sosuke Suzuki
f8b6453be9 config AmazonMobileAnalytics 2017-06-10 12:48:28 +09:00
SuenagaRyota
be625f8884 Merge pull request #626 from asmsuechan/iss-625
Fix a bug which is not showing dialog when user tries to export a snippet
2017-06-07 15:32:02 +09:00
asmsuechan
2271def5d3 Fix a bug which is not showing dialog when user tries to export a snippet 2017-06-07 15:23:07 +09:00
SuenagaRyota
275a8ea7cc Merge pull request #624 from asmsuechan/remove-unused-file
Remove an unused file
2017-06-07 14:19:22 +09:00
asmsuechan
dc236f33b1 Remove an unused file 2017-06-07 14:14:55 +09:00
SuenagaRyota
678d739e75 Merge pull request #623 from asmsuechan/add-emacs-keymap
Add emacs keymap
2017-06-07 12:48:39 +09:00
SuenagaRyota
8fe05a4c24 Merge pull request #548 from asmsuechan/add-a-module-findTitle
Add a module to find the title
2017-06-07 10:30:46 +09:00
asmsuechan
77adfdb9f0 Add emacs keymap 2017-06-07 09:37:21 +09:00
Kazu Yokomizo
30c94028fb Merge pull request #622 from BoostIO/fix-copy-button-layout
Fix copy button layout
2017-06-06 23:30:08 +09:00
Kazu Yokomizo
b5bf0780fa Fix copy button layout 2017-06-06 23:14:31 +09:00
SuenagaRyota
ad838d82ee Merge pull request #603 from nadr0/copyclipboard
Copy clipboard button for markdown code blocks
2017-06-06 21:38:00 +09:00
Kazu Yokomizo
d5ec0c0cdd Merge pull request #617 from CodeRi13/master
Translate contributing.md to korean
2017-06-05 16:16:50 +09:00
SuenagaRyota
ff29f1e0c6 Merge pull request #618 from BoostIO/revert-610-add-e2e-tests
Revert "Add e2e tests"
2017-06-05 13:09:10 +09:00
SuenagaRyota
1f58698a04 Revert "Add e2e tests" 2017-06-05 13:06:10 +09:00
CodeRi13
a275f331d0 Translate contributing.md to korean 2017-06-05 10:38:44 +09:00
Sota Sugiura
0862c6e059 Merge pull request #293 from asmsuechan/copy-image-on-dropped-into-CodeEditor
Add dataApi.copyImage for copying image to boostnote storage on an image dropped into CodeEditor
2017-06-05 01:29:11 +09:00
SuenagaRyota
46fddfd26c Merge pull request #614 from asmsuechan/add-documents
Add documents
2017-06-04 15:29:33 +09:00
asmsuechan
c547ccb4cb Update a document 2017-06-04 15:24:40 +09:00
asmsuechan
86e82fb149 Add required environments for building Boostnote on each local 2017-06-04 12:10:15 +09:00
SuenagaRyota
00a284bfbd Merge pull request #612 from asmsuechan/move-a-package-dev-to-prod
Move markdown-it-imsize dev-dependency to production
2017-06-03 20:52:40 +09:00
asmsuechan
f6fbec0a2e Move markdown-it-imsize dev-dependency to production 2017-06-03 20:47:43 +09:00
SuenagaRyota
b24c06bee6 Merge pull request #610 from asmsuechan/add-e2e-tests
Add e2e tests
2017-06-03 18:52:45 +09:00
asmsuechan
95e7f4f645 Fix errorhandling on cases of invalid notes 2017-06-03 18:47:56 +09:00
asmsuechan
4b75d501f5 Edit a e2e test for editting note 2017-06-03 18:28:40 +09:00
asmsuechan
b28d5c8b25 Fix the class name of modalClose button 2017-06-03 18:28:40 +09:00
SuenagaRyota
86e61661e6 Merge pull request #609 from asmsuechan/add-tests-for-search
Add tests for searchFromeNotes()
2017-06-03 17:24:33 +09:00
asmsuechan
cdd5717e63 Fix some pointed by eslint 2017-06-03 17:10:58 +09:00
asmsuechan
42bd7fb4fb Add tests for searchFromeNotes() 2017-06-03 17:04:22 +09:00
SuenagaRyota
66e478a001 Merge pull request #600 from BoostIO/feature-change-search-ux
change search ux
2017-06-03 16:41:36 +09:00
Kazu Yokomizo
c8259abcac Merge pull request #549 from LetItRock/#535
Fix for #535:
2017-06-03 14:35:52 +09:00
SuenagaRyota
d6d16a63a4 Merge pull request #608 from asmsuechan/fix-travis-node-version
Fix travis node version
2017-06-03 14:32:11 +09:00
asmsuechan
df8d1f0714 Add a comment 2017-06-03 14:24:28 +09:00
asmsuechan
fbbc6411c3 Fix the node_version to 4.x 2017-06-03 14:07:56 +09:00
Kazu Yokomizo
bc1e94fcab Merge pull request #607 from BoostIO/update-slack-link
Update slack link
2017-06-02 15:44:32 +09:00
Kazu Yokomizo
418439e3d5 Update slack group link 2017-06-02 15:27:36 +09:00
Kazu Yokomizo
46cbd04ba7 Update slack group link 2017-06-02 15:27:06 +09:00
asmsuechan
0ade6d9ece Add e2e tests for modal click and input texts 2017-06-01 17:26:28 +09:00
asmsuechan
823599192f Fix e2e tests 2017-06-01 15:59:12 +09:00
Sosuke Suzuki
9496ab88f7 fix spacings 2017-05-31 20:52:36 +09:00
Sosuke Suzuki
290e6ab170 change arg findByTag 2017-05-31 20:49:34 +09:00
asmsuechan
a9e3572f4f Add a e2e-test for Modal 2017-05-31 15:38:55 +09:00
Kazu Yokomizo
92b2b7dde3 Merge pull request #605 from BoostIO/improve-dark-theme
I improved the dark theme.
2017-05-31 15:26:55 +09:00
Kazu Yokomizo
dad1e40234 Fix white theme layout 2017-05-31 01:43:07 +09:00
Kazu Yokomizo
b75c8b0373 Fix code highlight 2017-05-31 01:26:40 +09:00
Sosuke Suzuki
fc4c471a87 fix spacing for eslint 2017-05-31 00:30:55 +09:00
Kazu Yokomizo
24de71f240 I improved the dark theme. 2017-05-30 23:33:59 +09:00
Sosuke Suzuki
805c39e60c refactor search function 2017-05-30 22:16:27 +09:00
Sosuke Suzuki
10e75041e8 add className 'searchInput' 2017-05-30 18:54:13 +09:00
Sosuke Suzuki
2364348df4 fix indent 2017-05-30 18:49:39 +09:00
Sosuke Suzuki
e643443660 split search function to module. 2017-05-30 18:27:57 +09:00
Kevin Nadro
d72e876b23 fixing eslint 2017-05-28 17:58:10 -05:00
Kevin Nadro
f3612774ba clipboard button is added 2017-05-28 17:31:23 -05:00
SuenagaRyota
67d8b02c49 Merge pull request #598 from dangvanthanh/master
#595 - Resize an image with markdown
2017-05-27 07:08:31 +09:00
Sosuke Suzuki
7abf53009a change search ux 2017-05-26 18:01:44 +09:00
Kazu Yokomizo
90bb4632b6 Merge pull request #599 from BoostIO/update-slack-link
Update slack link
2017-05-26 13:59:50 +09:00
Kazu Yokomizo
630da00235 Update slack link 2017-05-26 13:57:01 +09:00
Kazu Yokomizo
245e0dd7ee update slack group link 2017-05-26 13:56:23 +09:00
Dang Van Thanh
824e288a80 #595 - Resize an image with markdown 2017-05-26 10:58:39 +07:00
asmsuechan
99228f2e60 ♻️ Refactor findeTitle() 2017-05-23 17:01:07 +09:00
asmsuechan
0f71139eba Delete a comma pointed by eslint 2017-05-23 15:51:21 +09:00
asmsuechan
2bbe7056d1 Add test cases 2017-05-23 15:43:54 +09:00
asmsuechan
005d8f84fd Change for to some 2017-05-23 15:43:48 +09:00
asmsuechan
908cd7a890 Edit the method 2017-05-23 15:31:32 +09:00
asmsuechan
d4865adf6a Change findNoteTitle.find() to findNoteTitle.findNoteTitle() in test 2017-05-23 15:23:16 +09:00
asmsuechan
20411a2fd5 Change the function name of findNoteTitle.js from find to findNoteTitle 2017-05-23 15:23:16 +09:00
asmsuechan
19f8930f5a Fix to use strict equal 2017-05-23 15:23:16 +09:00
asmsuechan
ffc4ca1dd4 Add an unit test for findNoteTitle 2017-05-23 15:23:16 +09:00
asmsuechan
0bc9c6fb5a Change to use the module instead of a function findTitle() implemented inside the file 2017-05-23 15:23:11 +09:00
asmsuechan
983f453afd Add findTitle as a module 2017-05-23 15:17:47 +09:00
Kazu Yokomizo
60a0293495 Merge pull request #594 from BoostIO/edit-noteList-layout
If there is no tag, narrow the width of NoteList.
2017-05-22 21:19:36 +09:00
Kazu Yokomizo
4807d22763 If there is no tag, narrow the width of NoteList. 2017-05-22 20:13:47 +09:00
Kazu Yokomizo
e8d451bcbb Merge pull request #587 from BoostIO/fix-task-bar-ui
Fix task bar UI
2017-05-20 15:18:50 +09:00
Kazu Yokomizo
4809bb6f06 Change the z-index postiion 2017-05-20 15:09:52 +09:00
Kazu Yokomizo
d6d694cf66 Change z-index position and delete unnecessary class 2017-05-20 15:07:21 +09:00
Kazu Yokomizo
132e3c3088 Fix task bar UI 2017-05-20 14:53:06 +09:00
SuenagaRyota
3c7ff78549 Merge pull request #374 from BoostIO/feature_move_note_between_folder
Move note between folders
2017-05-20 14:33:55 +09:00
SuenagaRyota
adbdc2cb1c Merge pull request #510 from BoostIO/fix-note-title-bug-for-h1
fix the bug when using markdown syntax h1
2017-05-20 14:27:52 +09:00
Kazu Yokomizo
e52b74bbc9 Merge pull request #557 from BoostIO/feature-todo-percentage
display percentage of achievement of todo in markdown
2017-05-20 13:51:30 +09:00
Sosuke Suzuki
575f1b4b33 change from forEach to some 2017-05-20 12:28:11 +09:00
Sosuke Suzuki
a528c99900 change from 'undefined' to undefined 2017-05-20 12:24:58 +09:00
Sosuke Suzuki
e6047ed383 use String template literal 2017-05-20 11:38:09 +09:00
Kazu Yokomizo
381b7d960a Merge pull request #584 from BoostIO/update-slack-invitation
Update slack invitation
2017-05-18 17:01:15 +09:00
Kazu Yokomizo
045a8bde22 Update slack group link 2017-05-18 16:57:06 +09:00
Kazu Yokomizo
e528182c2a Update slack group link 2017-05-18 16:56:30 +09:00
Sosuke Suzuki
b86cdb461a fix the spacing 2017-05-18 01:27:37 +09:00
Sosuke Suzuki
7265f76770 for loop change to forEach 2017-05-18 00:31:46 +09:00
Sosuke Suzuki
2ed092279d avoid undefined 2017-05-18 00:07:48 +09:00
SuenagaRyota
7d71819be0 Merge pull request #578 from asmsuechan/add-a-documentation-of-e2e-testiong
Add a documentation of e2e testiong
2017-05-16 15:20:59 +09:00
asmsuechan
e848c74511 Fix the document in English 2017-05-16 15:17:20 +09:00
asmsuechan
968ed146b2 Fix the document in Japanese 2017-05-16 15:16:55 +09:00
asmsuechan
5e03f12875 Add a documentation of e2e testing in Japanese 2017-05-16 15:13:56 +09:00
asmsuechan
09f8e5f25a Add a documentation of e2e testing in English 2017-05-16 15:11:20 +09:00
SuenagaRyota
89f4ed3006 Merge pull request #471 from BoostIO/escButton-to-ReactComponent
made escButton ReactComponent
2017-05-13 17:15:21 +09:00
Sosuke Suzuki
8d14a9557d fix the indent 2017-05-13 17:07:02 +09:00
Sosuke Suzuki
513042d769 made escButton ReactComponent 2017-05-13 17:00:34 +09:00
Sosuke Suzuki
c28980c2a9 fix the spacing 2017-05-12 19:54:52 +09:00
Sosuke Suzuki
1c31ff4e98 use string template literal 2017-05-10 23:47:09 +09:00
Sosuke Suzuki
7c9d3904b3 change to forEach from for 2017-05-10 23:10:25 +09:00
Sosuke Suzuki
e23707f0a0 add + and * to matching pattern 2017-05-10 22:49:15 +09:00
Kazu Yokomizo
a952b18b96 Merge pull request #560 from BoostIO/update-slack-link-1
Update slack link 1
2017-05-09 21:55:29 +09:00
Kazu Yokomizo
35cc07bf63 Update readme-ja.md 2017-05-09 21:49:07 +09:00
Kazu Yokomizo
118bf18434 Update slack link 2017-05-09 21:48:40 +09:00
Sosuke Suzuki
34da15208b fix spacing 2017-05-06 16:57:15 +09:00
Sosuke Suzuki
e0dc62c00b fix indents 2017-05-06 16:40:42 +09:00
Sosuke Suzuki
b58df2f172 display percentage of achievement of todo in markdown 2017-05-06 16:30:03 +09:00
Pavlo Tymchuk
90846fab81 Fix for #535:
- hide/show code editor based on markdown editor state (could be CODE or PREVIEW);
- changed styles for code editor;
2017-05-04 23:09:48 +02:00
SuenagaRyota
efd80d5c0c Merge pull request #545 from LeoLamCY/revamp-keypress-handling
Revamp handling of multiple key press
2017-05-04 10:59:28 -07:00
SuenagaRyota
e37e28a22e Merge pull request #541 from asmsuechan/fix-travis-for-spectron
Fix viriables for travis
2017-05-03 09:45:24 -07:00
Leo Lam
a1e71b318c fix lint error again 2017-05-03 01:20:57 -04:00
Leo Lam
aee6541d45 fix lint errors 2017-05-03 01:17:13 -04:00
Leo Lam
50ad5e3791 minor improvement on multi-key detection
-check if number of keys pressed is the same as number of keys in a
shortcut key combo before matching to avoid incorrect detection
2017-05-03 01:04:50 -04:00
Leo Lam
b34d72f21a revamp handling of multi-key presses
- use keyCodes instead of strings to detect keys
- delete key from keyPressed array on key up
- fix #540
2017-05-03 00:29:18 -04:00
asmsuechan
e5ae420ef6 Fix viriables for travis 2017-05-02 09:49:49 -07:00
Sota Sugiura
7269750264 Merge pull request #502 from asmsuechan/add-spectron
Add spectron
2017-05-02 18:23:02 +09:00
Sota Sugiura
33fe3ff733 Merge pull request #527 from BoostIO/fix-add-description
Add description for package.json
2017-04-29 16:25:03 +09:00
sota1235
aa77180957 modify: backword compatibility 2017-04-29 16:24:08 +09:00
sota1235
3d80b6a4cd modify: add descriptoin (it is reuqired for building windows app) 2017-04-29 16:01:39 +09:00
Sota Sugiura
d76f9243a3 Merge pull request #524 from BoostIO/feature-v0-8-9
v0.8.9
2017-04-29 15:25:15 +09:00
sota1235
88f1a0d5cd v0.8.9 2017-04-29 15:22:15 +09:00
Kazu Yokomizo
26c435d6da Merge pull request #526 from BoostIO/change-noteitem-border-color
Change noteitem border color
2017-04-29 15:19:39 +09:00
Kazu Yokomizo
e66abdea2d Change the border color at NoteItemSimple 2017-04-29 15:11:48 +09:00
Kazu Yokomizo
c7d2eeb71a Change the border color at NoteItem 2017-04-29 15:07:13 +09:00
Kazu Yokomizo
0e8d681954 Merge pull request #525 from BoostIO/update-slack-link
Update slack link
2017-04-29 14:20:24 +09:00
Kazu Yokomizo
433d110cf0 Update slack invitation link 2017-04-29 14:17:48 +09:00
Kazu Yokomizo
4a514cd7bd Update slack invitation link 2017-04-29 14:17:10 +09:00
Kazu Yokomizo
417fee16bd Merge pull request #512 from LeoLamCY/fix-md-viewer-line-breaks
Fix md viewer line breaks when copying
2017-04-29 14:09:23 +09:00
Kazu Yokomizo
49a821d9ee Merge pull request #480 from SalvatoreTosti/master
Changed wordings on 'Make a Note' pane
2017-04-29 14:09:00 +09:00
Kazu Yokomizo
6a5ce098e0 Merge pull request #513 from bbtran/master
fixes (#504) scrollbar no longer appears above modal.
2017-04-29 12:47:27 +09:00
Kazu Yokomizo
1af73eebea Merge pull request #523 from BoostIO/change-donate-link
Change donate link
2017-04-29 12:31:16 +09:00
Sota Sugiura
b7ba29ac92 Merge pull request #341 from asmsuechan/fix-incorrect-tag-completion
Fix incorrect tag completion in code block
2017-04-29 12:24:50 +09:00
Kazu Yokomizo
133c2ec308 Change the donation link Patreon to Bountysource 2017-04-29 12:19:26 +09:00
Kazu Yokomizo
a70fe1bba8 Merge pull request #522 from BoostIO/change-star-layout
fix: modify the star layout at NoteItem
2017-04-29 12:09:53 +09:00
Kazu Yokomizo
6dcd653eac Merge pull request #520 from BoostIO/improvement-of-sidebar-uiux
Improvement of sidebar uiux
2017-04-29 11:17:03 +09:00
Kazu Yokomizo
db2f90b1ce fix: modify the star layout at NoteItem 2017-04-29 05:56:48 +09:00
Kazu Yokomizo
60e5665133 Fix the layout and UX of StorageItem at SIdebra 2017-04-28 16:07:55 +09:00
Kazu Yokomizo
7aa982849f Fix the layout and UX at create-folder-btn at sidebar 2017-04-28 15:42:46 +09:00
Kohei TAKATA
d94f7626c2 Merge pull request #477 from BoostIO/hotfix-fix-package-name
Fix package name
2017-04-28 00:39:06 +09:00
Benjamin Tran
549c289f81 fixes #504 scrollbar no longer appears above modal.
Edit NoteList style properties on modal component. Remove overflow to hide scrollbar on modal open.
2017-04-26 19:12:56 -07:00
Leo Lam
b35953d1f9 fix md viewer line breaks when copying
-set white-space to normal to remove extra space between lines
2017-04-26 19:37:12 -04:00
Leo
941c4aeb19 Merge pull request #2 from BoostIO/master
update fork
2017-04-26 14:08:30 -04:00
Sosuke Suzuki
11f7fcbaef fix the bug that is markdown titile starts with second letter 2017-04-26 18:32:46 +09:00
Sosuke Suzuki
6b8488ae0f fix the bug when using markdown syntax h1 2017-04-26 18:14:29 +09:00
asmsuechan
ee5268a07e Change to separation osx and linux 2017-04-25 17:05:10 -07:00
asmsuechan
28bc331318 Change to run only master branch 2017-04-25 11:48:45 -07:00
asmsuechan
098153b6ba Add osx support to .travis.yml
Change to run xvfb only linux
2017-04-25 09:19:46 -07:00
asmsuechan
878f31e91e Remove unnecessary break 2017-04-25 09:18:45 -07:00
asmsuechan
b40d09fa86 Edit .travis.yml to handle ES7 syntax problem 2017-04-25 00:08:59 -07:00
asmsuechan
eb48f48f6b Edit spectron.js to deal with linux 2017-04-25 00:08:49 -07:00
asmsuechan
7961008500 Edit gruntfile.js 2017-04-25 00:08:49 -07:00
asmsuechan
ff87c6b226 Fix .travis.yml to add grunt-cli because travis needs grunt to run $ grund pre-build for e2e test 2017-04-24 19:46:39 -07:00
asmsuechan
0c2807a08b Rename spectron-test.js to spectron.js because of avoidance from be ran it by npm run test 2017-04-24 19:42:02 -07:00
asmsuechan
f0cf369317 Edit .travis.yml for e2e test 2017-04-24 19:28:29 -07:00
asmsuechan
5e9954c060 Add a yarn task 2017-04-24 19:23:23 -07:00
asmsuechan
0c7bdf20af Add a smiple test to confirm Boostnote starts 2017-04-24 19:23:23 -07:00
Sosuke Suzuki
9c1179a6f9 Fixed indent which could not be corrected 2017-04-25 02:53:29 +09:00
Sosuke Suzuki
43cb290c80 fix the indent 2017-04-25 02:41:16 +09:00
Sosuke Suzuki
f8b7b7df9f change how to use dataApi and fix indent 2017-04-25 02:31:03 +09:00
Sosuke Suzuki
b73f0a8012 refactor some dirty code 2017-04-25 01:40:49 +09:00
Sota Sugiura
75b2c7bd2e Merge pull request #484 from asmsuechan/fix-delete-shortcut
Fix a shortcut for deletion
2017-04-24 23:14:42 +09:00
Leo
5fd9866eef Merge pull request #1 from BoostIO/master
update fork
2017-04-24 00:59:37 -04:00
asmsuechan
4e7204bdbc Add spectron 2017-04-23 12:13:58 -07:00
SuenagaRyota
ff7024e38f Merge pull request #488 from tkshnwesper/master
Added `Shift` to HotkeyTab.js
2017-04-23 00:21:05 -07:00
Saurabh
8c11a0b42d Added Shift to HotkeyTab.js 2017-04-23 12:43:39 +05:30
asmsuechan
2df295dc1d Fix styles by lint 2017-04-22 17:30:55 -07:00
asmsuechan
b695d27817 Add test for htmlTextHelper 2017-04-22 17:19:05 -07:00
asmsuechan
8e2fd300f6 Delete an encode table
because when & is encoded, it affect other encodes due to they use &
2017-04-22 16:14:09 -07:00
asmsuechan
1722e103fc Change methods to helper methods 2017-04-22 16:14:09 -07:00
asmsuechan
71464112ce Remove a disused condition 2017-04-22 16:14:09 -07:00
asmsuechan
003d8a1b21 Fix a bug on regexp of a question mark 2017-04-22 16:14:09 -07:00
asmsuechan
adf81175f3 Reduce the code 2017-04-22 16:14:09 -07:00
asmsuechan
39274ce483 Fix to handle with multiple entities in one line 2017-04-22 16:14:09 -07:00
asmsuechan
1daf07edeb Refactor to more readable 2017-04-22 16:14:09 -07:00
asmsuechan
cd2dc471c7 Fix to string literal 2017-04-22 16:14:09 -07:00
asmsuechan
6229ca7ac9 Refactor to ES6 2017-04-22 16:14:09 -07:00
asmsuechan
10043cc755 Fix to handle when codeBlocks is null 2017-04-22 16:14:09 -07:00
asmsuechan
e60a5430b4 Fix to replace only CodeBlock 2017-04-22 16:14:09 -07:00
asmsuechan
f7e0cb655f Add question mark 2017-04-22 16:14:09 -07:00
asmsuechan
04097ecfcd Fix incorrect tag completion in code block 2017-04-22 16:14:09 -07:00
asmsuechan
2222192bcd Fix to enable a shortcut for deleting a note 2017-04-22 15:38:55 -07:00
Salvatore Tosti
ae93c38d46 Changed wordings on 'Make a Note' pane
Note type descriptions are now more concise and uniform in style.
2017-04-22 08:16:05 -07:00
Sota Sugiura
9ff9dcbe6d Merge branch 'master' into hotfix-fix-package-name 2017-04-22 18:45:52 +09:00
sota1235
94d442af7d modify: fix package name 2017-04-22 18:43:56 +09:00
Sota Sugiura
6a711d6a71 Merge pull request #476 from BoostIO/v8-8-8
v0.8.8
2017-04-22 18:30:05 +09:00
sota1235
9d8e71aeb3 v8.8.8 2017-04-22 16:34:58 +09:00
Sota Sugiura
cfeeba209e Merge pull request #468 from BoostIO/feature-fix-text
Fix text on menu bar(macOS) and some refactor
2017-04-22 16:31:58 +09:00
Sota Sugiura
455029851a Merge pull request #474 from BoostIO/delete-escbutton-in-initimodal
delete the escButton in the InitModal
2017-04-22 16:19:32 +09:00
Sota Sugiura
d0f7baaad0 Merge pull request #473 from BoostIO/Fix-ConfigTab-Interface
Fix the config tab layout
2017-04-22 16:17:43 +09:00
Kazu Yokomizo
e3fb236139 Fix the config tab layout 2017-04-22 16:06:01 +09:00
Sosuke Suzuki
42296e421a delete the escButton in the InitModal 2017-04-22 16:05:22 +09:00
Sota Sugiura
c6f4ed7c8f Merge pull request #472 from BoostIO/Design-update
Fix the english typo
2017-04-22 15:45:09 +09:00
Kazu Yokomizo
e1fb36d64d Fix the border-left width at folder-selector 2017-04-22 15:33:05 +09:00
Sota Sugiura
48cf695e11 Merge branch 'master' into Design-update 2017-04-22 15:17:03 +09:00
Kazu Yokomizo
5b0e0c71a0 Fix the english typo 2017-04-22 14:59:53 +09:00
Sota Sugiura
c1a76b6fb4 Merge pull request #290 from BoostIO/featureSyntaxHighlightCheck
Feature syntax highlight check
2017-04-22 13:20:19 +09:00
Sota Sugiura
945a6306ec Merge pull request #469 from LeoLamCY/add-support-to-bold-selected-text-via-kb-shortcut
Add support to bold selected text via kb shortcut
2017-04-22 13:07:04 +09:00
sota1235
313bacf9dc modify: fix for ESLint 2017-04-22 13:00:25 +09:00
Sota Sugiura
9027f48dda Merge pull request #453 from bubuzzz/feature/double-click-to-rename-tab
double click on tab to rename
2017-04-22 12:58:29 +09:00
Sota Sugiura
eea8f7cdf4 Merge pull request #425 from AWEEKJ/feature_markdown_note
Fix new line problem in list and task list
2017-04-22 12:52:53 +09:00
Leo Lam
ffef239aa7 fix minor build error 2017-04-21 23:40:52 -04:00
Leo Lam
50fc15feea add support to bold selected text via kb shortcut
to improve upon #301
ctrl + : to bold a single word under caret or bold selected text if some
text is selected (highlighted)

#463
2017-04-21 23:32:57 -04:00
Leo Lam
2d7a37c872 Merge remote-tracking branch 'refs/remotes/BoostIO/master' 2017-04-21 23:24:44 -04:00
sota1235
db468fc095 modify: some refactor 2017-04-22 11:54:05 +09:00
sota1235
9a9f0035c2 modify: add label for quit button on macOS 2017-04-22 11:51:06 +09:00
Sota Sugiura
b9270cd040 Merge pull request #349 from asmsuechan/iss-332
Fix the screen become black on closing Boostnote when a state of Boostnote is fullscreen on mac
2017-04-22 11:44:44 +09:00
Kazu Yokomizo
65b1bd18c4 Merge pull request #465 from BoostIO/Design-update
Fix the loading layout
2017-04-21 20:48:44 +09:00
Kazu Yokomizo
c87ecc3d40 Fix the Statusbar layout 2017-04-21 20:23:33 +09:00
Kazu Yokomizo
e39e1648f9 Fix the loading layout 2017-04-21 20:07:14 +09:00
Kazu Yokomizo
091d2618a2 Merge pull request #462 from BoostIO/Design-update
Design update
2017-04-21 18:21:16 +09:00
Kazu Yokomizo
d039b17715 modify: Fix the SideNavFilter layout 2017-04-21 16:13:45 +09:00
Kazu Yokomizo
e350dca72c modify: Fix the star-btn layout at NoteDetail 2017-04-21 15:48:57 +09:00
Kazu Yokomizo
c07e334f03 modify: Fix the tag style at NoteDetail 2017-04-21 15:32:23 +09:00
Kazu Yokomizo
1ccfd8e392 modify: Fix the tag-list layout at NoteItem 2017-04-21 15:00:09 +09:00
Kazu Yokomizo
d22c40f0a5 modify: Fix the tag layout at note list 2017-04-21 14:53:25 +09:00
Kazu Yokomizo
3d37db6e54 modify: Fix the hover layout at SideNav 2017-04-21 14:33:16 +09:00
Kazu Yokomizo
22bd92916b modify: Fix the navtoggle-btn layout 2017-04-21 14:24:22 +09:00
Kazu Yokomizo
de303cf072 modify: Fix the sort-by-btn layout 2017-04-21 14:20:21 +09:00
Kazu Yokomizo
b22aad0678 modify: Fix the navtoggle-btn layout 2017-04-21 14:02:48 +09:00
Kazu Yokomizo
bf02f9b256 modify: Fix the layout of new-post-btn and status-bar 2017-04-21 13:45:04 +09:00
SuenagaRyota
6440ab423e Merge pull request #457 from SalvatoreTosti/master
Updated initial pieces of text to read more clearly in English
2017-04-20 22:16:53 -05:00
Salvatore Tosti
fceab73226 Updated initial pieces of text to read more clearly in English 2017-04-19 17:57:42 -07:00
Thai Tran
fded0ad3e8 double click on tab to rename 2017-04-19 15:05:47 +10:00
Kazu Yokomizo
294eb64686 Merge pull request #451 from BoostIO/Fix-slack-link
Fix slack group invitation
2017-04-19 10:15:45 +09:00
Kazu Yokomizo
851b28c482 Fix slack group invitation 2017-04-19 10:10:35 +09:00
Kazu Yokomizo
63fa2f1149 Fix slack group invitaition 2017-04-19 10:10:05 +09:00
Kazu Yokomizo
816d8decbd Merge pull request #443 from SalvatoreTosti/master
Changed wording in build.md and debug.md
2017-04-18 12:04:39 +09:00
Salvatore Tosti
85b4eedcd6 Changed wording in build.md and debug.md
I've adjusted the wording in the build and debug files to flow better and make more sense in English.
2017-04-17 19:38:20 -07:00
Kazu Yokomizo
901f40a669 Merge pull request #442 from BoostIO/Fix-typo
Fix typo in Infotab
2017-04-18 10:24:07 +09:00
Kazu Yokomizo
bae5f202a5 Fix typo in Infotab 2017-04-18 10:20:39 +09:00
Kazu Yokomizo
131f6780c2 Merge pull request #441 from SalvatoreTosti/master
Updated readme file to read more cleanly in English
2017-04-18 10:10:53 +09:00
Salvatore Tosti
a0e067cacf Updated readme file to read more cleanly in English
Made some small styling tweaks for greater uniformity within the readme document.
Also reworded a few sections to read more clearly.
2017-04-17 12:38:43 -07:00
Kazu Yokomizo
8cdcf537be Merge pull request #439 from BoostIO/update-info
Update information.
2017-04-18 00:57:38 +09:00
Kazu Yokomizo
575f5f160c Update information. 2017-04-18 00:55:31 +09:00
Kazu Yokomizo
d8fbac584c Merge pull request #438 from BoostIO/Fix-readme
Fix readme
2017-04-18 00:47:34 +09:00
Kazu Yokomizo
b73e1b04dc Fix readme 2017-04-17 18:21:12 +09:00
Kazu Yokomizo
3dd49c287d Merge pull request #424 from BoostIO/Design-update
Design update at v0.8.8
2017-04-15 13:00:36 +09:00
Kazu Yokomizo
6ce6a7036b Fix typo 2017-04-15 12:33:16 +09:00
SuenagaRyota
c120633f14 Merge pull request #426 from asmsuechan/edit-contributing.md
Edit contributing.md
2017-04-14 19:33:04 -07:00
asmsuechan
6e84b24309 Edit contributing.md 2017-04-14 18:52:48 -07:00
Kazu Yokomizo
343e35bb54 Fix the select-btn layout at setting modal in white theme 2017-04-14 17:14:45 +09:00
Kazu Yokomizo
09cf94d807 Fix to outline:none 2017-04-14 17:10:37 +09:00
Hanju Jo
a5531e20f2 Fix new line problem of list and task list 2017-04-14 17:09:30 +09:00
Kazu Yokomizo
0f311120af Fix the layout of NoteItem at SideNav 2017-04-14 16:42:01 +09:00
Kazu Yokomizo
614506cada Fix the hover/active layout at menubar in white theme 2017-04-14 15:45:52 +09:00
Kazu Yokomizo
7891d14a0a Fix the hover/active layout at NoteItemSimple 2017-04-14 15:38:45 +09:00
Kazu Yokomizo
2df12b6891 Fix the hover layout at NoteNavFilter in white theme 2017-04-14 15:28:27 +09:00
Kazu Yokomizo
97b42d6be1 Fix the hover/active layout at NoteItem in white theme 2017-04-14 15:26:45 +09:00
Kazu Yokomizo
39baadeb04 Fix hover/active layout at NoteItem 2017-04-14 15:23:52 +09:00
Kazu Yokomizo
a6f5452a85 Change the button color at setting modal 2017-04-13 20:45:26 +09:00
Kazu Yokomizo
29dc3bd550 Fix the layout of nav-btn at setting modal 2017-04-13 12:14:36 +09:00
Kazu Yokomizo
e103605956 Change the border-left at setting modal 2017-04-13 12:05:10 +09:00
Kazu Yokomizo
c510c2e540 Change the add-storage-btn at setting modal 2017-04-13 12:04:51 +09:00
Kazu Yokomizo
41d65e4132 Change the border-width at folder list 2017-04-13 11:46:41 +09:00
SuenagaRyota
b6cb532568 Merge pull request #422 from asmsuechan/iss-421
Update katex to 0.7.1
2017-04-12 14:27:36 -07:00
asmsuechan
a034ea3a05 Update katex to 0.7.1 2017-04-12 12:55:30 -07:00
Kazu Yokomizo
adeb45a9ce Fix the storage-btn layout at SideNav 2017-04-12 23:10:29 +09:00
Kazu Yokomizo
4ada755793 Change the info at InfoTag modal 2017-04-12 22:22:22 +09:00
Kazu Yokomizo
c4be052a49 Change the info at infoModal 2017-04-12 20:17:06 +09:00
Kazu Yokomizo
54c2d7bac9 Delete the border-line at Statusbar 2017-04-12 16:14:00 +09:00
Kazu Yokomizo
233ab17992 Change the default background-color of ui-btn at white theme 2017-04-12 15:08:51 +09:00
Kazu Yokomizo
e251ec64dc Fix the layout of SideNavFilter 2017-04-12 14:59:47 +09:00
Kazu Yokomizo
32bd6d76ee Change the All Notes icon at SideNavFilter 2017-04-12 14:48:52 +09:00
Kazu Yokomizo
3fc17634aa Merge pull request #418 from BoostIO/Update-slack-invitation
Update slack invitation
2017-04-12 12:45:20 +09:00
Kazu Yokomizo
555d725e7b Update slack group invitation link 2017-04-12 12:42:54 +09:00
Kazu Yokomizo
35416796b5 Update slack group invitation link 2017-04-12 12:42:14 +09:00
SuenagaRyota
6c737fe25f Merge pull request #399 from asmsuechan/remove-a-shortcut-fot-bold
Remove Ctrl-B shortcut for bold
2017-04-11 12:54:29 -07:00
Kazu Yokomizo
1b58e320aa Change the font color at dark theme 2017-04-11 00:47:13 +09:00
Kazu Yokomizo
658a90bf15 Fix the layout at NoteItem 2017-04-10 23:08:06 +09:00
Kazu Yokomizo
d092e75f3c Delete the border line at Statusbar 2017-04-10 22:11:44 +09:00
asmsuechan
162fae19cc Remove Ctrl-B shortcut for bold 2017-04-08 14:31:18 -07:00
Kazu Yokomizo
58f5035ec6 Change the star background-color when hover at NoteDetail 2017-04-08 16:58:52 +09:00
Kazu Yokomizo
c5076e4e95 Change the star background-color when hover 2017-04-08 16:54:36 +09:00
Kazu Yokomizo
28ef1e625c Fix the rename folder modal layout 2017-04-08 16:49:35 +09:00
Kazu Yokomizo
97441ccacb Fix the box-shadow 2017-04-08 16:46:11 +09:00
Kazu Yokomizo
6b29aed6c4 Fix the search modal layout 2017-04-08 16:40:26 +09:00
Kazu Yokomizo
31eb9caee4 Fix the dark layout at NoteList 2017-04-08 16:03:53 +09:00
Kazu Yokomizo
64cf34e673 Fix the make note modal layout at white theme 2017-04-08 15:57:59 +09:00
Kazu Yokomizo
8996ebb819 Fix the make note modal layout at dark theme 2017-04-08 15:53:31 +09:00
Kazu Yokomizo
a36c62044b Fix the create folder modal layout at dark theme 2017-04-08 15:49:43 +09:00
Kazu Yokomizo
13418109ea Fix the create folder modal layout at white theme 2017-04-08 15:37:55 +09:00
Kohei TAKATA
fe7c05aaa5 Merge pull request #393 from BoostIO/feature-use-yarn
Using yarn
2017-04-08 12:51:48 +09:00
Kazu Yokomizo
116e27e0db Fix the textarea layout at Snippet note 2017-04-08 01:04:32 +09:00
Kazu Yokomizo
6b135afe1a Change the font-size at FolderSelect 2017-04-07 19:20:49 +09:00
Kazu Yokomizo
7a9c4951a2 Fix the tag layout of white theme at NoteDetail 2017-04-07 19:08:34 +09:00
Kazu Yokomizo
041a51a70f Fix the tag layout of dark theme at NoteDetail 2017-04-07 19:04:09 +09:00
Kazu Yokomizo
7b4ff9906e Change the note-title-icon position at NoteList 2017-04-07 18:51:34 +09:00
Kazu Yokomizo
11ab5c7598 Fix the tag layout of white theme at NoteList 2017-04-07 18:45:16 +09:00
Kazu Yokomizo
64d53c611b Fix the tag layout of dark theme at NoteList 2017-04-07 18:43:36 +09:00
Kazu Yokomizo
657d69a0fb Fix the dark theme layout at NoteList 2017-04-07 15:25:59 +09:00
Kazu Yokomizo
62d39e6715 Change the StorageList layout 2017-04-07 15:12:46 +09:00
Kazu Yokomizo
a27d8192ee Change the white theme layout of NoteList 2017-04-07 15:05:18 +09:00
SuenagaRyota
41b69afe03 Merge pull request #385 from BoostIO/Change-trashButton-size
Change the trashButton size
2017-04-06 23:04:20 -07:00
sota1235
54b5af0741 modify: update docs 2017-04-07 14:39:10 +09:00
sota1235
d4060f8a5a add: using yarn 🎉 2017-04-07 14:37:13 +09:00
SuenagaRyota
2935d41aba Merge pull request #386 from clone1612/productionPruneFix
Fix for 'npm prune --production' deleting needed dependencies
2017-04-06 22:33:16 -07:00
Kazu Yokomizo
af6cd10e28 Change the layout at SideNav 2017-04-07 14:24:38 +09:00
SuenagaRyota
435c80d870 Merge pull request #392 from asmsuechan/rm-finder-menu
Remove finder-menu
2017-04-06 21:30:04 -07:00
asmsuechan
775cec32da Remove finder-menu
it's no longer required
2017-04-06 21:22:25 -07:00
SuenagaRyota
e8cc7abadc Merge pull request #364 from Hastegan/master
Uniform the accelerator notation
2017-04-06 21:08:55 -07:00
Kazu Yokomizo
c1051afdc0 Change the SideNav layout 2017-04-07 00:38:49 +09:00
Kazu Yokomizo
573d3ce11e Fix the layout on NoteList 2017-04-06 23:25:38 +09:00
Kazu Yokomizo
0a89dcc6d8 Change the font-size at SideNav 2017-04-06 23:09:24 +09:00
Kazu Yokomizo
d45033ae8e Change the font-size at NoteList 2017-04-06 22:59:09 +09:00
Kazu Yokomizo
313e8b8c98 Fix the dark theme layout of Sidebar and NoteList 2017-04-06 22:11:59 +09:00
Sosuke Suzuki
25685dc8b0 Several small fixes 2017-04-06 21:52:23 +09:00
Jannick Hemelhof
d6a78dfe28 Fix for prune deleting needed packages 2017-04-05 14:53:51 +02:00
Kazu Yokomizo
de45852790 Change the trashButton size 2017-04-05 11:38:44 +09:00
Kazu Yokomizo
c6a505cb44 Merge pull request #384 from BoostIO/update-slack-invitiaon
Update slack invitiaon
2017-04-05 11:36:10 +09:00
Kazu Yokomizo
44427a40b7 Update readme
Update slack group invitation link.
2017-04-05 11:32:06 +09:00
Kazu Yokomizo
8a2ac08c0a Update readme
Update the slack group invitation link.
2017-04-05 11:31:12 +09:00
Kazu Yokomizo
7babf66d5f Merge pull request #340 from asmsuechan/remove-a-menu-on-delete
Remove a menu which is shown on clicked the trash button
2017-04-05 11:26:18 +09:00
Sosuke Suzuki
50cd0b794b change color with hover during dragging 2017-04-05 10:08:09 +09:00
Sosuke Suzuki
720f07f62c Move note between folders 2017-04-01 02:36:48 +09:00
hastegan
6daffbcafa uniform shortcut notation 2017-03-29 01:10:55 +02:00
Sota Sugiura
b76729e836 Merge pull request #362 from BoostIO/Edit-slackgrou-link
Edit slack group invitation link
2017-03-28 15:14:49 +09:00
Kazu Yokomizo
b2294e0fc9 modify: Edited the slack group invitation link
at Japanese
2017-03-28 14:49:21 +09:00
Kazu Yokomizo
3559737e8e modify: Edited the slack group invitation link 2017-03-28 14:48:15 +09:00
asmsuechan
40b7ce607b Add it to snippet note 2017-03-27 11:49:54 -07:00
asmsuechan
1de67a00cb Remove a menu which is shown on clicked the trash button 2017-03-27 11:44:42 -07:00
SuenagaRyota
6b4b44dba8 Merge pull request #358 from asmsuechan/modify-documents
Modify and add documents
2017-03-27 02:37:44 -07:00
asmsuechan
c424cc5d33 Change the sentence 2017-03-26 23:55:09 -07:00
asmsuechan
5b71d010b4 Add docs/ja/debug.md 2017-03-26 23:49:18 -07:00
asmsuechan
b9457d3e33 Add docs/debug.md 2017-03-26 23:49:08 -07:00
asmsuechan
60e267409c Modify ja/build.md accompanied by npm run dev-start 2017-03-26 23:20:04 -07:00
asmsuechan
e6a2521143 Modify build.md accompanied by npm run dev-start 2017-03-26 23:15:36 -07:00
Sota Sugiura
ae36ed2b46 Merge pull request #357 from asmsuechan/add-concurrently
Add concurrently for running local environment more easily
2017-03-27 14:30:21 +09:00
asmsuechan
fb2ed81fd3 Add concurrently for running local environment more easily 2017-03-26 22:04:47 -07:00
Sosuke Suzuki
a74651b515 load javascript mode of codemirror & clean up dirty codes 2017-03-25 15:32:45 +09:00
SuenagaRyota
6904c192e4 Merge pull request #352 from redcom/fix-288
fix: #288 Fixed Snippet tabs overwriting other tabs when closed
2017-03-23 13:41:54 -07:00
Razvan Moraru
6540d2670c better formatting 2017-03-23 21:01:49 +01:00
Razvan Moraru
966ba06bc4 change let to const 2017-03-23 17:50:39 +01:00
Razvan Moraru
3b4921b848 fix: #288 Fixed Snippet tabs overwriting other tabs when closed 2017-03-23 09:20:02 +01:00
SuenagaRyota
b11e10ac07 Merge pull request #347 from BoostIO/add-slack-group-link
Add slack group link
2017-03-22 18:50:03 -07:00
asmsuechan
2ec7ba04f5 Fix by lint 2017-03-22 00:21:49 -07:00
asmsuechan
095910d156 Fix the screen become black on closing Boostnote when a state of Boostnote is fullscreen on mac 2017-03-22 00:00:45 -07:00
Kazu Yokomizo
c39463aea8 modify: add the join to slack group link
Ver Japanese
2017-03-21 15:54:29 +09:00
Kazu Yokomizo
87e47c7ffb modify: Add the join to slack group link 2017-03-21 15:52:43 +09:00
Sota Sugiura
359f6734c5 Merge pull request #317 from BoostIO/feature-add-esilnt-rule
Add prefer-const rule and fix code
2017-03-21 15:16:48 +09:00
sota1235
1d3e71cf49 fix: for ESLint 2017-03-21 15:14:03 +09:00
Sota Sugiura
1ab449cecf Merge branch 'master' into feature-add-esilnt-rule 2017-03-21 15:04:14 +09:00
Sota Sugiura
44dd609134 Merge pull request #289 from kostaldavid8/master
Smart bullets
2017-03-21 15:02:25 +09:00
kostaldavid8
1e8e161a33 remove console.log 2017-03-20 19:42:14 +01:00
kostaldavid8
c56d232e58 Added + as bullet, bug fix 2017-03-20 19:22:31 +01:00
Sota Sugiura
8315b75587 Merge pull request #342 from sota1235/feature-v0-8-7
v0.8.7
2017-03-20 16:11:24 +09:00
sota1235
562b0592af v0.8.7 2017-03-20 15:39:34 +09:00
Sota Sugiura
1fd1bed01a Merge pull request #343 from asmsuechan/remove-markdown-it-toc
Remove markdown-it-toc because an errors are happening
2017-03-20 15:38:32 +09:00
asmsuechan
4f116cba34 Remove markdown-it-toc because an errors are happening 2017-03-19 23:32:51 -07:00
Sota Sugiura
9d1d57f183 Merge pull request #331 from asmsuechan/fix-the-behavior-of-lock
Fix the behavior of a feature which locks the editor
2017-03-20 15:31:44 +09:00
asmsuechan
6feeee8933 Refactor the styles of the buttons 2017-03-19 22:17:01 -07:00
asmsuechan
5541c0dc38 Refactor styles of the buttons 2017-03-19 22:11:02 -07:00
asmsuechan
4a8054faed Fix the design of the trash button on snippet note 2017-03-19 22:04:19 -07:00
asmsuechan
bbced7be25 Fix the background-color of button 2017-03-19 21:56:41 -07:00
asmsuechan
893a92c87b Fix from reviews 2017-03-19 12:39:46 -07:00
asmsuechan
4055ce19cd Fix the design of buttons of TopBar on dark theme 2017-03-19 11:18:17 -07:00
asmsuechan
bcf27233bc Fix a style of the lock button 2017-03-19 01:31:28 -07:00
asmsuechan
45111e1610 Change the styleName info-right-button to control-trashButton because it's not good name
* fix the position of lock button
2017-03-19 01:20:04 -07:00
asmsuechan
2af86dfa3e Fix the action of hover 2017-03-19 01:02:47 -07:00
Sota Sugiura
1b474e1c28 Merge pull request #337 from BoostIO/Change-the-tray-icon
Changed the tray icon when mouse on.
2017-03-19 16:45:15 +09:00
Sota Sugiura
c4370694cc Merge pull request #295 from asmsuechan/add-a-shortcut-for-jump-to-top
Add a shortcut which jumps to top by Ctrl-G
2017-03-19 16:43:15 +09:00
asmsuechan
91f24d96b9 Fix a bug which cannot read a property when moves to other folder on locking 2017-03-19 00:41:55 -07:00
Kazu Yokomizo
bb0b74e889 Changed the tray icon when mouse on. 2017-03-19 16:20:55 +09:00
asmsuechan
525ab900bd Fix == to === 2017-03-19 00:18:09 -07:00
asmsuechan
31c04de7b6 Change the name list:top to list:jumpToTop 2017-03-19 00:18:09 -07:00
asmsuechan
dea0c4287b Fix let to const 2017-03-19 00:18:09 -07:00
asmsuechan
cec4b3132c Add a shortcut which jumps to top by Ctrl-G 2017-03-19 00:18:05 -07:00
asmsuechan
f3ed22dd51 Enable to appear a tooltip for the LockButton 2017-03-18 23:19:43 -07:00
asmsuechan
6aa9104076 Fix not to be shown the lock button if config.editor.switchPreview is
RIGHTCLICK
2017-03-18 23:19:43 -07:00
asmsuechan
e7fd18967b Change a state name editorStatus to isLockButtonShown 2017-03-18 23:19:43 -07:00
asmsuechan
8a5558db55 Change a name showlockbutton to togglelockbutton 2017-03-18 23:19:43 -07:00
asmsuechan
4767f15e9b Fix the behavior of a feature what locks the editor 2017-03-18 23:19:43 -07:00
Sota Sugiura
b7ca4668e9 Merge pull request #301 from asmsuechan/add-a-shortcut-for-supporting-to-input-bold
Add a shortcut for supporting to input bold
2017-03-19 15:08:17 +09:00
Sota Sugiura
70e637fada Merge pull request #326 from asmsuechan/refactor-typos
Fix typos
2017-03-19 14:09:29 +09:00
SuenagaRyota
459b0ff030 Merge pull request #316 from asmsuechan/fix-the-design-of-li
Fix the design of li
2017-03-18 10:58:30 -07:00
SuenagaRyota
2903788fd4 Merge pull request #330 from BoostIO/feature-dragDrop-svg
dragged svg file is turns not into xml text
2017-03-17 22:54:04 -07:00
Sosuke Suzuki
af0fdb9277 move the line under L57 2017-03-18 14:49:46 +09:00
SuenagaRyota
41a58583dc Merge pull request #324 from BoostIO/feature_note_title_markdown_sharp
ignore # in the code block
2017-03-17 21:48:16 -07:00
Sosuke Suzuki
c80a26fe0b dragged svg file is turns not into xml text 2017-03-18 13:44:35 +09:00
Sosuke Suzuki
806c3bbaf9 delete unnecessary } and correct the indent 2017-03-18 12:27:43 +09:00
Sosuke Suzuki
fe1c197138 reduce indent 2017-03-18 03:02:04 +09:00
Sosuke Suzuki
b577ca2bc2 Refactor the dirty code 2017-03-18 01:58:15 +09:00
asmsuechan
70a97a6a2a Fix a typo 2017-03-16 13:30:24 -07:00
Sosuke Suzuki
034f46792b ignore # in the code block 2017-03-17 03:42:17 +09:00
SuenagaRyota
3dc1b59753 Merge pull request #307 from BoostIO/feature-trashCan-icon
I changed the button  deleting snnipet and markdown from ... to trash can.
2017-03-15 13:55:31 -07:00
SuenagaRyota
98b761f1d1 Merge pull request #322 from BoostIO/featureSuccessfullyDeleteSubtab
The snippet subtab was successfully deleted.
2017-03-15 13:51:11 -07:00
Sosuke Suzuki
712301436d I crrected indents 2017-03-16 02:54:57 +09:00
Sosuke Suzuki
4243afb033 remove the extra file, and correct indents 2017-03-16 02:34:26 +09:00
Sosuke Suzuki
0f43485606 The snippet subtab was successfully deleted. 2017-03-16 01:36:58 +09:00
Sota Sugiura
b91b88f16e Merge pull request #321 from BoostIO/Change-the-tray-icon
Change the tray icons.
2017-03-14 14:24:02 +09:00
Kazu Yokomizo
2f2c500e4a Change the tray icons. 2017-03-14 13:59:59 +09:00
sota1235
7065fad69b modify: change warning level for no-lone-blocks rule 2017-03-13 18:55:16 +09:00
sota1235
6fcbca6b10 refactor: by ESLint 2017-03-13 18:40:12 +09:00
sota1235
93b15f2a7a modify: change warning level for no-undef 2017-03-13 18:36:21 +09:00
sota1235
df9d8ff735 modify: change warning level for no-unused-var 2017-03-13 18:33:39 +09:00
sota1235
fda17e044e modify: change warning level for prefer-const rule 2017-03-13 18:26:56 +09:00
sota1235
b4e54fc149 modify: npm script 2017-03-13 18:26:39 +09:00
asmsuechan
48514d1020 Change an arg name md to mdElement 2017-03-12 16:07:40 -07:00
asmsuechan
49a4ec5e16 Enable CTRL + B in a word to make it bold 2017-03-12 16:04:08 -07:00
asmsuechan
c3e92b3b81 Fix if clauses 2017-03-12 16:04:00 -07:00
asmsuechan
e78492983a Add a shortcut for supporting to input bold 2017-03-12 16:02:52 -07:00
asmsuechan
0f3230110c Change to use const instead of let 2017-03-10 20:40:11 -08:00
asmsuechan
65573bd4db Add comments 2017-03-10 20:33:16 -08:00
asmsuechan
928df018dc Fix the assginment of targetStorage 2017-03-10 20:33:16 -08:00
asmsuechan
b2187b72ab Fix let to const 2017-03-10 20:33:16 -08:00
asmsuechan
aae2bddd32 Improve the Promise of copyImage 2017-03-10 20:33:11 -08:00
asmsuechan
b6eddf0821 Add dataApi.copyImage for copying image to boostnote storage on an image to boostnote storage on an image doropped into CodeEditor 2017-03-10 20:31:54 -08:00
sota1235
fac0abaed6 modify: add prefer-const rule and fix code 2017-03-10 10:12:23 +09:00
asmsuechan
a6bd239592 Fix the design of li
* fix the design of markdown-it-TOC
2017-03-09 13:04:14 -08:00
SuenagaRyota
7845bbd881 Merge pull request #310 from Gansgar/master
Added Table of Contents and two small bug fixes
2017-03-09 12:09:50 -08:00
SuenagaRyota
68bc440749 Merge pull request #298 from asmsuechan/fix-drop-an-image-on-CodeEditor-and-MarkdownPreview
Disable dragging an image to MarkdownPreview and fix the behavior of an image dropped on CodeEditor.
2017-03-08 15:38:27 +09:00
SuenagaRyota
6dbe3cec69 Merge pull request #283 from asmsuechan/add-lock-to-CodeEditor
Enable lock in MarkdownEditor
2017-03-07 11:16:55 +09:00
georg
850c339bb3 bug fix to select all
- at least on OSX fixed bug, that would select all text when clicking,
opening or any other action was done
2017-03-04 18:37:04 +01:00
georg
57835d0e32 Added ToC support
- added `markdown-it-toc-and-anchor` into the project
- integrated it, create a table of contents every in a markup by adding
`@[TOC]`
2017-03-04 17:48:17 +01:00
georg
ac2c50c8bc Fixed background of taskListItem
- fixed background bug when using a taskListItem with the light design
2017-03-04 17:18:30 +01:00
Kohei TAKATA
7296cbe4ec Merge pull request #309 from BoostIO/feature-v0-8-6
v0.8.6
2017-03-04 14:06:31 +09:00
Kohei TAKATA
16061a7eba v0.8.6 2017-03-04 13:04:18 +09:00
Sosuke Suzuki
566fe92589 change the icon to delete snippet and markdown 2017-03-03 02:13:13 +09:00
asmsuechan
83cef13f1c Change let to const 2017-02-21 23:30:37 +09:00
asmsuechan
4bb9533049 Fix prevention of an image dropped on MarkdownPreview and fix the behavior of an image dropped on CodeEditor 2017-02-21 00:14:03 +09:00
kostaldavid8
d07c62e266 Merge branch 'master' of https://github.com/BoostIO/Boostnote 2017-02-18 23:36:09 +01:00
SuenagaRyota
8beb661af4 Merge pull request #291 from kostaldavid8/image-drag-fix
Image drag fix
2017-02-18 21:06:16 +09:00
Sosuke Suzuki
5a201dd1b9 correction the pointed out code 2017-02-18 12:26:38 +09:00
asmsuechan
aa0ad3bb70 Fix from review 2017-02-18 12:18:55 +09:00
kostaldavid8
f7fb531902 Fixed image drag and drop
Added escaping and changed function that wasn't working
2017-02-17 10:31:41 +01:00
kostaldavid8
c65db4e2b0 Fixed image drag and drop
Added escaping and changed function that wasn't working
2017-02-17 10:04:55 +01:00
Sota Sugiura
b32b38bb0d Merge pull request #287 from ericsolomon/274_font_color_rename_folder_modal
Fix font color for dark theme rename folder modal
2017-02-16 21:38:37 -08:00
kostaldavid8
d6171dc502 Smart numbered lists, too
Has auto increment, but no auto indent on tab, I don't know what to do
2017-02-16 13:18:17 +01:00
Sosuke Suzuki
7b5a7aabed add HighLightCheckEditor 2017-02-16 13:00:45 +09:00
kostaldavid8
77eb19af40 Code style fixes 2017-02-15 23:30:56 +01:00
kostaldavid8
e68d535fa2 Smart bullets
When you hit enter on a line with a bullet, you get a new one on the new line.
Also when you hit tab after a bullet, it automatically indents.
It makes typing with bullets much more pleasant.
2017-02-15 22:18:20 +01:00
Eric Solomon
6e5f6cc739 Fix font color for dark theme rename folder modal 2017-02-14 03:21:23 -06:00
asmsuechan
bbeeeccb31 Fix to use by preventDefault 2017-02-11 23:09:03 +09:00
asmsuechan
e9525fae22 Change the order of focus and emit 'editor:lock' 2017-02-11 23:09:01 +09:00
asmsuechan
672d409bf2 Enable to show the lock icon only the Editor state is CODE 2017-02-11 17:52:11 +09:00
Kohei TAKATA
6624178864 Merge pull request #284 from BoostIO/feature-v0-8-5
v0.8.5
2017-02-11 17:47:30 +09:00
Kohei TAKATA
4a66c6717c v0.8.5 2017-02-11 16:08:31 +09:00
Kohei TAKATA
dd76bc027b Merge pull request #282 from BoostIO/fix-windows-taskbar-icon
Fix windows taskbar icon
2017-02-11 16:02:58 +09:00
asmsuechan
74ee6ae6ce Add lock icon to NoteDetail 2017-02-11 15:48:38 +09:00
Kohei TAKATA
1ae3f295f3 Remove unused variable 2017-02-11 15:47:25 +09:00
Kohei TAKATA
3cb2ce41fe Merge pull request #278 from EmEpsilon/fix-239-on-windows
refs #239 [Fix] cannot open finder with using hotkey on windows
2017-02-11 15:38:21 +09:00
Kohei TAKATA
5534319e93 Fix windows taskbar icon 2017-02-11 14:05:14 +09:00
EmEpsilon
c7373c15a5 Fix: cannot open finder with using hotkey 2017-02-10 00:35:31 +09:00
Sota Sugiura
dbf1d6403b Merge pull request #216 from asmsuechan/decode-for-codemirror
Decodes HTML entity in code area
2017-02-08 05:44:49 -08:00
Sosuke Suzuki
743b220953 unfinished syntaxHighLightCheck 2017-02-04 14:41:26 +09:00
Sota Sugiura
95d74c6f5b Merge pull request #269 from sota1235/feature-v0-8-4
v0.8.4
2017-01-28 14:22:42 +09:00
sota1235
f04b7db9fc v0.8.4 2017-01-28 13:54:54 +09:00
Sota Sugiura
900fa023fb Merge pull request #261 from asmsuechan/change-Ctrl-E-customizable
refs #260 Change a shortcut Ctrl-E to Ctrl-W
2017-01-28 13:37:08 +09:00
asmsuechan
ad9da44afb Move a shortcut escapeFromCodeEditor from CodeEditor to MarkdownEditor, because it's not customizable 2017-01-28 13:27:34 +09:00
asmsuechan
c827717202 refs #260 Change a shortcut Ctrl-E to Ctrl-W
it escapes CodeEditor to MarkdownPreview
2017-01-28 12:51:49 +09:00
Sota Sugiura
7d3caa3c2e Merge pull request #267 from asmsuechan/fix-ctrl-e-shortcut
Fix Ctrl + E shortcut on escape from CodeEditor
2017-01-28 12:48:32 +09:00
asmsuechan
fde7fbccac Fix Ctrl + E shortcut on escape from CodeEditor 2017-01-27 01:27:29 +09:00
Sota Sugiura
56f06fa7d5 Merge pull request #262 from BoostIO/Changed-the-order-of-English-and-Japanese
Changed the order of English and Japanese.
2017-01-26 11:24:07 +09:00
Sota Sugiura
c0fba82e73 Merge pull request #265 from BoostIO/delete-readme-ko
Delete readme-ko.md
2017-01-26 11:23:34 +09:00
Kohei TAKATA
5438cd14a0 Merge pull request #257 from sota1235/feature-fix_style_for_side_nav
Fix style for side nav
2017-01-25 19:20:47 +09:00
Sota Sugiura
0d642b308d Merge pull request #264 from BoostIO/add-maintainer-1
add-maintainer(ja)
2017-01-25 01:29:52 +09:00
Sota Sugiura
0b96472f72 Merge pull request #259 from BoostIO/add-maintainer
Add maintainer
2017-01-25 01:29:37 +09:00
Kazu Yokomizo
675d0ed08c Delete readme-ko.md 2017-01-25 01:29:24 +09:00
Kazu Yokomizo
9c0f5c31c2 add-maintainer(ja) 2017-01-25 01:22:19 +09:00
Kazu Yokomizo
09ce59fd04 Deleted (English) 2017-01-25 01:14:54 +09:00
Kazu Yokomizo
98cd83c4e0 Changed the order of English and Japanese. 2017-01-24 19:18:52 +09:00
Kazu Yokomizo
1aec386656 Add maintainer 2017-01-21 18:45:28 +09:00
sota1235
b03cd9cd99 modify: fix style for side nav 2017-01-21 17:34:02 +09:00
Sota Sugiura
27265e210f Merge pull request #256 from BoostIO/release-v0-8-3
v0.8.3
2017-01-21 16:51:45 +09:00
sota1235
c392c5d178 v0.8.3 2017-01-21 16:32:27 +09:00
Sota Sugiura
11fe420fac Merge pull request #255 from BoostIO/featureEscButton
Feature esc button
2017-01-21 16:30:45 +09:00
Sota Sugiura
9b17a8fb5b Merge pull request #250 from asmsuechan/add-drop-image
Dropping images into CodeEditor
2017-01-21 16:28:56 +09:00
Sota Sugiura
27f3fd0032 Merge pull request #241 from asmsuechan/iss-208
Fixes syntax hilight of inline code on Preview
2017-01-21 16:14:58 +09:00
Sota Sugiura
1672d9fa5f Merge pull request #235 from asmsuechan/add-focus-shortcut
Adds shortcuts
2017-01-21 16:12:13 +09:00
asmsuechan
59c9e11879 Change the color in <code> tag on preview 2017-01-21 16:12:03 +09:00
asmsuechan
4523743150 Fix by review
refs: https://github.com/BoostIO/Boostnote/pull/235#pullrequestreview-17800321
2017-01-21 16:06:14 +09:00
Sosuke Suzuki
2fdbe9de96 unify finder backgroundcolor 2017-01-21 16:04:55 +09:00
asmsuechan
a617976c78 Fix by review
refs: https://github.com/BoostIO/Boostnote/pull/250#pullrequestreview-17801164
2017-01-21 15:57:42 +09:00
Sota Sugiura
7201a98d78 Merge pull request #245 from asmsuechan/add-md-and-text-exporter
Add export as txt/md
2017-01-21 15:54:01 +09:00
Sosuke Suzuki
472560e2bf correction EscButton in darkmode 2017-01-21 15:52:06 +09:00
Sota Sugiura
96753fe0a0 Merge pull request #254 from BoostIO/featureFinderBackgroundColor
unify finder backgroundcolor
2017-01-21 15:51:15 +09:00
Sosuke Suzuki
83c2fdd161 unify finder backgroundcolor 2017-01-21 15:44:52 +09:00
asmsuechan
911ce7572f Fix by review
refs: https://github.com/BoostIO/Boostnote/pull/245#pullrequestreview-17800372
2017-01-21 15:44:48 +09:00
Sota Sugiura
0a24d7d4a7 Merge pull request #247 from asmsuechan/iss-246
Fix a Bug when using the Finder Window with markdown Notes
2017-01-21 15:05:51 +09:00
Sota Sugiura
c542062d4d Merge pull request #253 from BoostIO/featureEscButton
changeEscButton
2017-01-21 14:55:13 +09:00
Sosuke Suzuki
eb7a195cce NewNoteModal fineModification 2017-01-21 14:50:10 +09:00
Sosuke Suzuki
23a356164e changeEscButton 2017-01-21 14:31:38 +09:00
asmsuechan
de19c51061 Change to use Object.assign by checking keyPressed and remove unnecessary processing 2017-01-21 01:04:33 +09:00
asmsuechan
221b6a2938 Alert users try to export md/txt in SNIPPET 2017-01-20 18:56:33 +09:00
asmsuechan
cda9d53c8e Add image dropper 2017-01-19 01:32:06 +09:00
Sota Sugiura
f043b0ffb3 Merge pull request #248 from whizark/more-zoom-options
modify: add more zoom options (140-200%)
2017-01-19 00:23:07 +09:00
Sota Sugiura
28e0590327 Merge pull request #244 from asmsuechan/hotfix-an-error-occurs-on-update
Fix a bug due to event handler of before-quit on update
2017-01-19 00:15:56 +09:00
asmsuechan
ec6de1b91b Fix typo 2017-01-19 00:01:14 +09:00
asmsuechan
2b0bdbf1c8 Fix pointed part by review 2017-01-18 12:03:29 +09:00
asmsuechan
f48864a2e7 Fix pointed part by review 2017-01-18 10:09:12 +09:00
Whizark
94c6578675 modify: add more zoom options (140-200%)
* https://github.com/BoostIO/Boostnote/issues/31#issuecomment-267843725
2017-01-18 02:52:26 +09:00
asmsuechan
2af2399971 refs #247 Add fixed blur handler 2017-01-17 11:27:37 +09:00
asmsuechan
ebea01cecf refs #246 Fix a Bug when using the Finder Window with markdown Notes 2017-01-16 22:17:25 +09:00
asmsuechan
5d1db1de31 Add export as txt/md 2017-01-16 13:09:59 +09:00
asmsuechan
6c528625d8 Fix a bug due to event handler of before-quit on update 2017-01-16 04:36:23 +09:00
asmsuechan
2a60ba95e0 refs #208 Fixes syntax hilight of inline code on Preview 2017-01-14 20:45:53 +09:00
asmsuechan
cdb079dc81 refs #226 Enables to use multiple key for shortcut 2017-01-14 20:26:43 +09:00
asmsuechan
2ac0d93caf refs #226 Adds Control to Hint of Hotkey 2017-01-14 19:17:47 +09:00
asmsuechan
41977e8726 refs #226 Adds shortcuts which move next note and prior note to main-menu 2017-01-14 19:17:43 +09:00
asmsuechan
b9e6a56a83 refs #226 Changes to toggle by Ctrl + S 2017-01-14 19:17:41 +09:00
asmsuechan
2468c8311f refs #226 Adds focus to search shortcut to main-menu 2017-01-14 19:17:39 +09:00
asmsuechan
e8e05b20cd refs #226 Adds blur shortcut on Editor 2017-01-14 19:17:35 +09:00
asmsuechan
5bd0a446f1 refs #226 Adds a shortcut which focuses the note 2017-01-14 19:17:24 +09:00
asmsuechan
a641a7b3e4 Decodes HTML entity in code area 2017-01-08 12:29:43 +09:00
128 changed files with 9630 additions and 1312 deletions

View File

@@ -1,6 +1,10 @@
{
"extends": ["standard", "standard-jsx"],
"rules": {
"no-useless-escape": 0
"no-useless-escape": 0,
"prefer-const": "warn",
"no-unused-vars": "warn",
"no-undef": "warn",
"no-lone-blocks": "warn"
}
}

5
Backers.md Normal file
View File

@@ -0,0 +1,5 @@
Become a [backer](https://salt.bountysource.com/teams/boostnote) and support Boostnote!
You can support Boostnote from $ 5 a month!
# Backers
[Kazu Yokomizo](https://twitter.com/kazup_bot)

1
ISSUE_TEMPLATE.md Normal file
View File

@@ -0,0 +1 @@
Please paste some **screenshots** with opening the developer tool if you report a bug.

View File

@@ -1,8 +1,8 @@
GPL-3.0
Boostnote - the simplest note app
Boostnote - an open source note-taking app made for programmers just like you.
Copyright (C) 2016 MAISIN&CO.
Copyright (C) 2017 Maisin&Co., Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,8 @@
import React, { PropTypes } from 'react'
import _ from 'lodash'
import CodeMirror from 'codemirror'
import path from 'path'
import copyImage from 'browser/main/lib/dataApi/copyImage'
CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js'
@@ -54,19 +56,40 @@ export default class CodeEditor extends React.Component {
indentWithTabs: this.props.indentType !== 'space',
keyMap: this.props.keyMap,
inputStyle: 'textarea',
dragDrop: false,
extraKeys: {
Tab: function (cm) {
const cursor = cm.getCursor()
const line = cm.getLine(cursor.line)
if (cm.somethingSelected()) cm.indentSelection('add')
else {
if (cm.getOption('indentWithTabs')) {
cm.execCommand('insertTab')
const tabs = cm.getOption('indentWithTabs')
if (line.trimLeft() === '- ' || line.trimLeft() === '* ' || line.trimLeft() === '+ ') {
cm.execCommand('goLineStart')
if (tabs) {
cm.execCommand('insertTab')
} else {
cm.execCommand('insertSoftTab')
}
cm.execCommand('goLineEnd')
} else {
cm.execCommand('insertSoftTab')
if (tabs) {
cm.execCommand('insertTab')
} else {
cm.execCommand('insertSoftTab')
}
}
}
},
'Cmd-T': function (cm) {
// Do nothing
},
Enter: 'newlineAndIndentContinueMarkdownList',
'Ctrl-C': (cm) => {
if (cm.getOption('keyMap').substr(0, 3) === 'vim') {
document.execCommand('copy')
}
return CodeMirror.Pass
}
}
})
@@ -155,6 +178,7 @@ export default class CodeEditor extends React.Component {
this.editor.setValue(this.props.value)
this.editor.clearHistory()
this.editor.on('change', this.changeHandler)
this.editor.refresh()
}
setValue (value) {
@@ -163,6 +187,23 @@ export default class CodeEditor extends React.Component {
this.editor.setCursor(cursor)
}
handleDropImage (e) {
e.preventDefault()
const imagePath = e.dataTransfer.files[0].path
const filename = path.basename(imagePath)
copyImage(imagePath, this.props.storageKey).then((imagePath) => {
const imageMd = `![${filename}](${path.join('/:storage', imagePath)})`
this.insertImageMd(imageMd)
})
}
insertImageMd (imageMd) {
const textarea = this.editor.getInputField()
const cm = this.editor
textarea.value = `${textarea.value.substr(0, textarea.selectionStart)}${imageMd}${textarea.value.substr(textarea.selectionEnd)}`
}
render () {
let { className, fontFamily, fontSize } = this.props
fontFamily = _.isString(fontFamily) && fontFamily.length > 0
@@ -180,6 +221,7 @@ export default class CodeEditor extends React.Component {
fontFamily: fontFamily.join(', '),
fontSize: fontSize
}}
onDrop={(e) => this.handleDropImage(e)}
/>
)
}

View File

@@ -3,19 +3,32 @@ import CSSModules from 'browser/lib/CSSModules'
import styles from './MarkdownEditor.styl'
import CodeEditor from 'browser/components/CodeEditor'
import MarkdownPreview from 'browser/components/MarkdownPreview'
import eventEmitter from 'browser/main/lib/eventEmitter'
const _ = require('lodash')
class MarkdownEditor extends React.Component {
constructor (props) {
super(props)
// char codes for ctrl + w
this.escapeFromEditor = [17, 87]
// ctrl + shift + ;
this.supportMdSelectionBold = [16, 17, 186]
this.state = {
status: 'PREVIEW',
renderValue: props.value
renderValue: props.value,
keyPressed: new Set(),
isLocked: false
}
this.lockEditorCode = () => this.handleLockEditor()
}
componentDidMount () {
this.value = this.refs.code.value
eventEmitter.on('editor:lock', this.lockEditorCode)
}
componentDidUpdate () {
@@ -30,6 +43,7 @@ class MarkdownEditor extends React.Component {
componentWillUnmount () {
this.cancelQueue()
eventEmitter.off('editor:lock', this.lockEditorCode)
}
queueRendering (value) {
@@ -69,11 +83,14 @@ class MarkdownEditor extends React.Component {
this.refs.code.blur()
this.refs.preview.focus()
}
eventEmitter.emit('topbar:togglelockbutton', this.state.status)
})
}
}
handleBlur (e) {
if (this.state.isLocked) return
this.setState({ keyPressed: new Set() })
let { config } = this.props
if (config.editor.switchPreview === 'BLUR') {
let cursorPosition = this.refs.code.editor.getCursor()
@@ -83,6 +100,7 @@ class MarkdownEditor extends React.Component {
this.refs.preview.focus()
this.refs.preview.scrollTo(cursorPosition.line)
})
eventEmitter.emit('topbar:togglelockbutton', this.state.status)
}
}
@@ -98,6 +116,7 @@ class MarkdownEditor extends React.Component {
}, () => {
this.refs.code.focus()
})
eventEmitter.emit('topbar:togglelockbutton', this.state.status)
}
}
@@ -134,6 +153,7 @@ class MarkdownEditor extends React.Component {
} else {
this.refs.code.focus()
}
eventEmitter.emit('topbar:togglelockbutton', this.state.status)
}
reload () {
@@ -142,8 +162,49 @@ class MarkdownEditor extends React.Component {
this.renderPreview(this.props.value)
}
handleKeyDown (e) {
if (this.state.status !== 'CODE') return false
const keyPressed = this.state.keyPressed
keyPressed.add(e.keyCode)
this.setState({ keyPressed })
let isNoteHandlerKey = (el) => { return keyPressed.has(el) }
if (keyPressed.size === this.escapeFromEditor.length &&
!this.state.isLocked && this.state.status === 'CODE' &&
this.escapeFromEditor.every(isNoteHandlerKey)) {
document.activeElement.blur()
}
if (keyPressed.size === this.supportMdSelectionBold.length && this.supportMdSelectionBold.every(isNoteHandlerKey)) {
this.addMdAroundWord('**')
}
}
addMdAroundWord (mdElement) {
if (this.refs.code.editor.getSelection()) {
return this.addMdAroundSelection(mdElement)
}
const currentCaret = this.refs.code.editor.getCursor()
const word = this.refs.code.editor.findWordAt(currentCaret)
const cmDoc = this.refs.code.editor.getDoc()
cmDoc.replaceRange(mdElement, word.anchor)
cmDoc.replaceRange(mdElement, { line: word.head.line, ch: word.head.ch + mdElement.length })
}
addMdAroundSelection (mdElement) {
this.refs.code.editor.replaceSelection(`${mdElement}${this.refs.code.editor.getSelection()}${mdElement}`)
}
handleKeyUp (e) {
const keyPressed = this.state.keyPressed
keyPressed.delete(e.keyCode)
this.setState({ keyPressed })
}
handleLockEditor () {
this.setState({ isLocked: !this.state.isLocked })
}
render () {
let { className, value, config } = this.props
let { className, value, config, storageKey } = this.props
let editorFontSize = parseInt(config.editor.fontSize, 10)
if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14
@@ -153,6 +214,11 @@ class MarkdownEditor extends React.Component {
let previewStyle = {}
if (this.props.ignorePreviewPointerEvents) previewStyle.pointerEvents = 'none'
const cachedStorageList = JSON.parse(localStorage.getItem('storages'))
if (!_.isArray(cachedStorageList)) throw new Error('Target storage doesn\'t exist.')
const storage = _.find(cachedStorageList, {key: storageKey})
if (storage === undefined) throw new Error('Target storage doesn\'t exist.')
return (
<div className={className == null
? 'MarkdownEditor'
@@ -160,8 +226,13 @@ class MarkdownEditor extends React.Component {
}
onContextMenu={(e) => this.handleContextMenu(e)}
tabIndex='-1'
onKeyDown={(e) => this.handleKeyDown(e)}
onKeyUp={(e) => this.handleKeyUp(e)}
>
<CodeEditor styleName='codeEditor'
<CodeEditor styleName={this.state.status === 'CODE'
? 'codeEditor'
: 'codeEditor--hide'
}
ref='code'
mode='GitHub Flavored Markdown'
value={value}
@@ -171,6 +242,7 @@ class MarkdownEditor extends React.Component {
fontSize={editorFontSize}
indentType={config.editor.indentType}
indentSize={editorIndentSize}
storageKey={storageKey}
onChange={(e) => this.handleChange(e)}
onBlur={(e) => this.handleBlur(e)}
/>
@@ -194,6 +266,7 @@ class MarkdownEditor extends React.Component {
onMouseUp={(e) => this.handlePreviewMouseUp(e)}
onMouseDown={(e) => this.handlePreviewMouseDown(e)}
onCheckboxClick={(e) => this.handleCheckboxClick(e)}
storagePath={storage.path}
/>
</div>
)

View File

@@ -4,8 +4,14 @@
.codeEditor
absolute top bottom left right
.hide
z-index 0
opacity 0
pointer-events none
.codeEditor--hide
@extend .codeEditor
@extend .hide
.preview
display block
@@ -17,7 +23,5 @@
.preview--hide
@extend .preview
z-index 0
opacity 0
pointer-events none
@extend .hide

View File

@@ -6,25 +6,15 @@ 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
}
import eventEmitter from 'browser/main/lib/eventEmitter'
import fs from 'fs'
import htmlTextHelper from 'browser/lib/htmlTextHelper'
import copy from 'copy-to-clipboard'
const { remote } = require('electron')
const { app } = remote
const path = require('path')
const dialog = remote.dialog
const markdownStyle = require('!!css!stylus?sourceMap!./markdown.styl')[0][1]
const appPath = 'file://' + (process.env.NODE_ENV === 'production'
@@ -49,12 +39,34 @@ body {
}
code {
font-family: ${codeBlockFontFamily.join(', ')};
background-color: rgba(0,0,0,0.04);
color: #CC305F;
}
.lineNumber {
${lineNumber && 'display: block !important;'}
font-family: ${codeBlockFontFamily.join(', ')};
}
.clipboardButton {
color: rgba(147,147,149,0.8);;
fill: rgba(147,147,149,1);;
border-radius: 50%;
margin: 7px;
border: none;
background-color: transparent;
outline: none;
height: 32px;
width: 32px;
cursor: pointer;
}
.clipboardButton:hover {
transition: 0.2s;
color: #939395;
fill: #939395;
background-color: rgba(0,0,0,0.1);
}
h1, h2 {
border: none;
}
@@ -68,6 +80,10 @@ h2 {
padding-bottom: 0.2em;
margin: 1em 0 0.37em;
}
body p {
white-space: normal;
}
`
}
@@ -90,6 +106,10 @@ export default class MarkdownPreview extends React.Component {
this.mouseUpHandler = (e) => this.handleMouseUp(e)
this.anchorClickHandler = (e) => this.handlePreviewAnchorClick(e)
this.checkboxClickHandler = (e) => this.handleCheckboxClick(e)
this.saveAsTextHandler = () => this.handleSaveAsText()
this.saveAsMdHandler = () => this.handleSaveAsMd()
this.linkClickHandler = this.handlelinkClick.bind(this)
}
handlePreviewAnchorClick (e) {
@@ -134,6 +154,31 @@ export default class MarkdownPreview extends React.Component {
if (this.props.onMouseUp != null) this.props.onMouseUp(e)
}
handleSaveAsText () {
this.exportAsDocument('txt')
}
handleSaveAsMd () {
this.exportAsDocument('md')
}
exportAsDocument (fileType) {
const options = {
filters: [
{ name: 'Documents', extensions: [fileType] }
],
properties: ['openFile', 'createDirectory']
}
dialog.showSaveDialog(remote.getCurrentWindow(), options,
(filename) => {
if (filename) {
fs.writeFile(filename, this.props.value, (err) => {
if (err) throw err
})
}
})
}
componentDidMount () {
this.refs.root.setAttribute('sandbox', 'allow-scripts')
this.refs.root.contentWindow.document.body.addEventListener('contextmenu', this.contextMenuHandler)
@@ -149,12 +194,20 @@ export default class MarkdownPreview extends React.Component {
this.refs.root.contentWindow.document.addEventListener('mousedown', this.mouseDownHandler)
this.refs.root.contentWindow.document.addEventListener('mouseup', this.mouseUpHandler)
this.refs.root.contentWindow.document.addEventListener('drop', this.preventImageDroppedHandler)
this.refs.root.contentWindow.document.addEventListener('dragover', this.preventImageDroppedHandler)
eventEmitter.on('export:save-text', this.saveAsTextHandler)
eventEmitter.on('export:save-md', this.saveAsMdHandler)
}
componentWillUnmount () {
this.refs.root.contentWindow.document.body.removeEventListener('contextmenu', this.contextMenuHandler)
this.refs.root.contentWindow.document.removeEventListener('mousedown', this.mouseDownHandler)
this.refs.root.contentWindow.document.removeEventListener('mouseup', this.mouseUpHandler)
this.refs.root.contentWindow.document.removeEventListener('drop', this.preventImageDroppedHandler)
this.refs.root.contentWindow.document.removeEventListener('dragover', this.preventImageDroppedHandler)
eventEmitter.off('export:save-text', this.saveAsTextHandler)
eventEmitter.off('export:save-md', this.saveAsMdHandler)
}
componentDidUpdate (prevProps) {
@@ -198,11 +251,26 @@ export default class MarkdownPreview extends React.Component {
el.removeEventListener('click', this.checkboxClickHandler)
})
let { value, theme, indentSize, codeBlockTheme } = this.props
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
el.removeEventListener('click', this.linkClickHandler)
})
let { value, theme, indentSize, codeBlockTheme, storagePath } = this.props
this.refs.root.contentWindow.document.body.setAttribute('data-theme', theme)
const codeBlocks = value.match(/(```)(.|[\n])*?(```)/g)
if (codeBlocks !== null) {
codeBlocks.forEach((codeBlock) => {
value = value.replace(codeBlock, htmlTextHelper.encodeEntities(codeBlock))
})
}
this.refs.root.contentWindow.document.body.innerHTML = markdown.render(value)
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('.taskListItem'), (el) => {
el.parentNode.parentNode.style.listStyleType = 'none'
})
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
el.addEventListener('click', this.anchorClickHandler)
})
@@ -211,6 +279,15 @@ export default class MarkdownPreview extends React.Component {
el.addEventListener('click', this.checkboxClickHandler)
})
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
el.addEventListener('click', this.linkClickHandler)
})
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('img'), (el) => {
if (!/\/:storage/.test(el.src)) return
el.src = `file:///${path.join(storagePath, 'images', path.basename(el.src))}`
})
codeBlockTheme = consts.THEMES.some((_theme) => _theme === codeBlockTheme)
? codeBlockTheme
: 'default'
@@ -219,7 +296,17 @@ export default class MarkdownPreview extends React.Component {
let syntax = CodeMirror.findModeByName(el.className)
if (syntax == null) syntax = CodeMirror.findModeByName('Plain Text')
CodeMirror.requireMode(syntax.mode, () => {
let content = el.innerHTML
let content = htmlTextHelper.decodeEntities(el.innerHTML)
const copyIcon = document.createElement('i')
copyIcon.innerHTML = '<button class="clipboardButton"><svg width="13" height="13" viewBox="0 0 1792 1792" ><path d="M768 1664h896v-640h-416q-40 0-68-28t-28-68v-416h-384v1152zm256-1440v-64q0-13-9.5-22.5t-22.5-9.5h-704q-13 0-22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h704q13 0 22.5-9.5t9.5-22.5zm256 672h299l-299-299v299zm512 128v672q0 40-28 68t-68 28h-960q-40 0-68-28t-28-68v-160h-544q-40 0-68-28t-28-68v-1344q0-40 28-68t68-28h1088q40 0 68 28t28 68v328q21 13 36 28l408 408q28 28 48 76t20 88z"/></svg></button>'
copyIcon.onclick = (e) => {
copy(content)
this.notify('Saved to Clipboard!', {
body: 'Paste it wherever you want!',
silent: true
})
}
el.parentNode.appendChild(copyIcon)
el.innerHTML = ''
el.parentNode.className += ` cm-s-${codeBlockTheme} CodeMirror`
CodeMirror.runMode(content, syntax.mime, el, {
@@ -237,7 +324,7 @@ export default class MarkdownPreview extends React.Component {
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('.flowchart'), (el) => {
Raphael.setWindow(this.getWindow())
try {
let diagram = flowchart.parse(decodeHTMLEntities(el.innerHTML))
let diagram = flowchart.parse(htmlTextHelper.decodeEntities(el.innerHTML))
el.innerHTML = ''
diagram.drawSVG(el, opts)
_.forEach(el.querySelectorAll('a'), (el) => {
@@ -253,7 +340,7 @@ export default class MarkdownPreview extends React.Component {
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('.sequence'), (el) => {
Raphael.setWindow(this.getWindow())
try {
let diagram = SequenceDiagram.parse(decodeHTMLEntities(el.innerHTML))
let diagram = SequenceDiagram.parse(htmlTextHelper.decodeEntities(el.innerHTML))
el.innerHTML = ''
diagram.drawSVG(el, {theme: 'simple'})
_.forEach(el.querySelectorAll('a'), (el) => {
@@ -289,6 +376,26 @@ export default class MarkdownPreview extends React.Component {
}
}
preventImageDroppedHandler (e) {
e.preventDefault()
e.stopPropagation()
}
notify (title, options) {
if (global.process.platform === 'win32') {
options.icon = path.join('file://', global.__dirname, '../../resources/app.png')
}
return new window.Notification(title, options)
}
handlelinkClick (e) {
const noteHash = e.target.href.split('/').pop()
const regexIsNoteLink = /^(.{20})-(.{20})$/
if (regexIsNoteLink.test(noteHash)) {
eventEmitter.emit('list:jump', noteHash)
}
}
render () {
let { className, style, tabIndex } = this.props
return (
@@ -310,5 +417,6 @@ MarkdownPreview.propTypes = {
onMouseUp: PropTypes.func,
onMouseDown: PropTypes.func,
className: PropTypes.string,
value: PropTypes.string
value: PropTypes.string,
storagePath: PropTypes.string
}

View File

@@ -0,0 +1,18 @@
import React, {PropTypes} from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './ModalEscButton.styl'
const ModalEscButton = ({
handleEscButtonClick
}) => (
<button styleName='escButton' onClick={handleEscButtonClick}>
<div styleName='esc-mark'>x</div>
<div styleName='esc-text'>esc</div>
</button>
)
ModalEscButton.propTypes = {
handleEscButtonClick: PropTypes.func.isRequired
}
export default CSSModules(ModalEscButton, styles)

View File

@@ -0,0 +1,14 @@
.escButton
height 50px
position absolute
background-color transparent
color $ui-inactive-text-color
border none
top 1px
right 10px
text-align center
width top-bar--height
height top-bar-height
.esc-mark
font-size 15px

View File

@@ -13,7 +13,7 @@ import styles from './NoteItem.styl'
*/
const TagElement = ({ tagName }) => (
<span styleName='item-bottom-tagList-item' key={tagName}>
{tagName}
#{tagName}
</span>
)
@@ -39,21 +39,24 @@ const TagElementList = (tags) => {
* @param {boolean} isActive
* @param {Object} note
* @param {Function} handleNoteClick
* @param {Function} handleNoteContextMenu
* @param {Function} handleDragStart
* @param {string} dateDisplay
*/
const NoteItem = ({ isActive, note, dateDisplay, handleNoteClick, handleNoteContextMenu }) => (
const NoteItem = ({ isActive, note, dateDisplay, handleNoteClick, handleDragStart }) => (
<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}`)}
onDragStart={e => handleDragStart(e, note)}
draggable='true'
>
<div styleName='item-wrapper'>
<div styleName='item-bottom-time'>{dateDisplay}</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' />
}
<div styleName='item-title'>
{note.title.trim().length > 0
? note.title
@@ -61,23 +64,18 @@ const NoteItem = ({ isActive, note, dateDisplay, handleNoteClick, handleNoteCont
}
</div>
<div styleName='item-bottom-time'>{dateDisplay}</div>
{note.isStarred
? <i styleName='item-star' className='fa fa-star' /> : ''
}
<div styleName='item-bottom'>
<div styleName='item-bottom-tagList'>
{note.tags.length > 0
? TagElementList(note.tags)
: ''
: <span styleName='item-bottom-tagList-empty' />
}
</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>
)
@@ -91,10 +89,12 @@ NoteItem.propTypes = {
type: PropTypes.string.isRequired,
title: PropTypes.string.isrequired,
tags: PropTypes.array,
isStarred: PropTypes.bool.isRequired
isStarred: PropTypes.bool.isRequired,
isTrashed: PropTypes.bool.isRequired
}),
handleNoteClick: PropTypes.func.isRequired,
handleNoteContextMenu: PropTypes.func.isRequired
handleDragStart: PropTypes.func.isRequired,
handleDragEnd: PropTypes.func.isRequired
}
export default CSSModules(NoteItem, styles)

View File

@@ -7,63 +7,72 @@ $control-height = 30px
.item
position relative
padding 0 25px
padding 0 20px
user-select none
cursor pointer
background-color $ui-noteList-backgroundColor
transition background-color 0.15s
transition background-color 0.2s
&:hover
background-color alpha($ui-active-color, 20%)
&:active
background-color $ui-active-color
color white
background-color alpha($ui-button--active-backgroundColor, 40%)
.item-title
.item-title-empty
.item-bottom-tagList-empty
.item-bottom-time
.item-title-icon
color white
.item-bottom-time
transition 0.15s
color $ui-text-color
.item-bottom-tagList-item
background-color transparent
color white
background-color alpha(white, 0.6)
color $ui-text-color
.item-star
color $ui-favorite-star-button-color
&:active
background-color $ui-button--active-backgroundColor
color $ui-text-color
.item-title
.item-title-icon
.item-bottom-time
transition 0.15s
color $ui-text-color
.item-bottom-tagList-item
background-color alpha(white, 0.6)
color $ui-text-color
.item-wrapper
padding 20px 0
padding 15px 0
border-bottom $ui-border
.item--active
@extend .item
background-color $ui-active-color
color white
background-color $ui-button--active-backgroundColor
color $ui-text-color
.item-title
.item-title-empty
.item-bottom-tagList-empty
.item-bottom-time
.item-title-icon
color white
color $ui-text-color
.item-bottom-tagList-item
background-color transparent
color white
background-color alpha(white, 0.6)
color $ui-text-color
.item-wrapper
border-color transparent
.item-star
color $ui-favorite-star-button-color
&:hover
background-color $ui-active-color
background-color $ui-button--active-backgroundColor
.item-title-icon
position relative
font-size 12px
color $ui-inactive-text-color
.item-title
font-size 14px
height 40px
box-sizing border-box
line-height 24px
padding-top 5px
padding-bottom 20px
position relative
top -12px
left 20px
padding-right 15px
padding-bottom 4px
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
@@ -74,7 +83,6 @@ $control-height = 30px
position relative
bottom 0px
margin-top 2px
height 20px
font-size 12px
line-height 20px
overflow ellipsis
@@ -84,37 +92,36 @@ $control-height = 30px
flex 1
overflow ellipsis
line-height 20px
color #FFFFFF
padding-top 7px
padding-left 2px
margin-right 27px
.item-bottom-tagList-item
font-size 12px
font-size 11px
margin-right 8px
padding 0 10px
padding 0
height 20px
box-sizing border-box
border-radius 20px
border-radius 2px
padding 1px 2px
vertical-align middle
background-color $ui-tag-backgroundColor
color #FFFFFF
.item-bottom-tagList-empty
background-color white
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
font-size 11px
padding-left 2px
padding-bottom 2px
.item-star
position absolute
top 20px
right 29px
right 5px
bottom 0px
width 34px
height 34px
color $ui-favorite-star-button-color
font-size 14px
color alpha($ui-favorite-star-button-color, 60%)
font-size 12px
padding 0
border-radius 17px
@@ -126,42 +133,59 @@ body[data-theme="dark"]
.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%)
transition 0.15s
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
.item-title
.item-title-icon
.item-bottom-time
transition 0.15s
color $ui-dark-text-color
.item-bottom-tagList-item
transition 0.15s
background-color alpha($ui-dark-button--active-backgroundColor, 40%)
color $ui-dark-text-color
&:active
transition 0.15s
background-color $ui-dark-button--active-backgroundColor
.item-title
.item-title-icon
.item-bottom-time
transition 0.15s
color $ui-dark-text-color
.item-bottom-tagList-item
transition 0.15s
background-color alpha(white, 10%)
color $ui-dark-text-color
.item-wrapper
border-color $ui-dark-borderColor
border-color alpha($ui-dark-button--active-backgroundColor, 60%)
.item--active
@extend .item
border-color $ui-dark-borderColor
background-color $ui-active-color
background-color $ui-dark-button--active-backgroundColor
.item-wrapper
border-color transparent
.item-title
color white
.item-title-icon
.item-bottom-time
color $ui-dark-text-color
.item-bottom-tagList-item
background-color transparent
color white
.item-bottom-tagList-empty
color white
&:hover
background-color $ui-active-color
background-color alpha(white, 10%)
color $ui-dark-text-color
.item-title
color $ui-dark-text-color
color $ui-inactive-text-color
.item-title-icon
color $ui-darkinactive-text-color
color $ui-inactive-text-color
.item-title-empty
color $ui-dark-inactive-text-color
color $ui-inactive-text-color
.item-bottom-tagList-item
background-color $ui-dark-tag-backgroundColor
color $ui-dark-text-color
background-color alpha($ui-dark-button--active-backgroundColor, 40%)
color $ui-inactive-text-color
.item-bottom-tagList-empty
color $ui-inactive-text-color

View File

@@ -10,16 +10,17 @@ import styles from './NoteItemSimple.styl'
* @param {boolean} isActive
* @param {Object} note
* @param {Function} handleNoteClick
* @param {Function} handleNoteContextMenu
* @param {Function} handleDragStart
*/
const NoteItemSimple = ({ isActive, note, handleNoteClick, handleNoteContextMenu }) => (
const NoteItemSimple = ({ isActive, note, handleNoteClick, handleDragStart }) => (
<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}`)}
onDragStart={e => handleDragStart(e, note)}
draggable='true'
>
<div styleName='item-simple-title'>
{note.type === 'SNIPPET_NOTE'
@@ -43,7 +44,7 @@ NoteItemSimple.propTypes = {
title: PropTypes.string.isrequired
}),
handleNoteClick: PropTypes.func.isRequired,
handleNoteContextMenu: PropTypes.func.isRequired
handleDragStart: PropTypes.func.isRequired
}
export default CSSModules(NoteItemSimple, styles)

View File

@@ -7,42 +7,46 @@ $control-height = 30px
.item-simple
position relative
padding 0 25px
padding 0 20px
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
background-color alpha($ui-button--active-backgroundColor, 40%)
.item-simple-title
.item-simple-title-empty
.item-simple-title-icon
color white
color $ui-text-color
&:active
background-color $ui-button--active-backgroundColor
color $ui-text-color
.item-simple-title
.item-simple-title-empty
.item-simple-title-icon
color $ui-text-color
.item-simple--active
@extend .item-simple
background-color $ui-active-color
color white
background-color $ui-button--active-backgroundColor
color $ui-text-color
.item-simple-title
.item-simple-title-empty
border-color transparent
color white
color $ui-text-color
.item-simple-title-icon
color white
color $ui-text-color
&:hover
background-color $ui-active-color
background-color $ui-button--active-backgroundColor
.item-simple-title
font-size 14px
font-size 13px
height 40px
box-sizing border-box
line-height 24px
padding-top 8px
overflow ellipsis
color $ui-text-color
color $ui-inactive-text-color
border-bottom $ui-border
.item-simple-title-icon
@@ -63,24 +67,36 @@ body[data-theme="dark"]
border-color $ui-dark-borderColor
background-color $ui-dark-noteList-backgroundColor
&:active
background-color $ui-active-color
background-color $ui-dark-button--active-backgroundColor
.item-simple-title
.item-simple-title-icon
.item-simple-bottom-time
.item-simple-bottom-tagList-item
transition 0.15s
color $ui-dark-text-color
&:hover
background-color alpha($ui-active-color, 20%)
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
.item-simple-title
.item-simple-title-icon
.item-simple-bottom-time
.item-simple-bottom-tagList-item
transition 0.15s
color $ui-dark-text-color
.item-simple--active
@extend .item-simple
border-color $ui-dark-borderColor
background-color $ui-active-color
background-color $ui-dark-button--active-backgroundColor
.item-simple-title
.item-simple-title-empty
color white
border-color transparent
&:hover
background-color $ui-active-color
.item-simple-title-icon
.item-simple-bottom-time
color $ui-dark-text-color
.item-simple-bottom-tagList-item
background-color transparent
color $ui-dark-text-color
.item-simple-title
color $ui-dark-text-color
border-color $ui-dark-borderColor
color $ui-inactive-text-color
border-color alpha($ui-dark-button--active-backgroundColor, 60%)
.item-simple-title-icon
color $ui-darkinactive-text-color

View File

@@ -1,24 +0,0 @@
import React, { PropTypes } from 'react'
import md5 from 'md5'
export default class ProfileImage extends React.Component {
render () {
let className = this.props.className == null ? 'ProfileImage' : 'ProfileImage ' + this.props.className
let email = this.props.email != null ? this.props.email : ''
let src = 'http://www.gravatar.com/avatar/' + md5(email.trim().toLowerCase()) + '?s=' + this.props.size
return (
<img
className={className}
width={this.props.size}
height={this.props.size}
src={src} />
)
}
}
ProfileImage.propTypes = {
email: PropTypes.string,
size: PropTypes.string,
className: PropTypes.string
}

View File

@@ -15,21 +15,27 @@ import styles from './SideNavFilter.styl'
*/
const SideNavFilter = ({
isFolded, isHomeActive, handleAllNotesButtonClick,
isStarredActive, handleStarredButtonClick
isStarredActive, handleStarredButtonClick, isTrashedActive, handleTrashedButtonClick
}) => (
<div styleName={isFolded ? 'menu--folded' : 'menu'}>
<button styleName={isHomeActive ? 'menu-button--active' : 'menu-button'}
onClick={handleAllNotesButtonClick}
>
<i className='fa fa-book fa-fw' />
<i className='fa fa-archive fa-fw' />
<span styleName='menu-button-label'>All Notes</span>
</button>
<button styleName={isStarredActive ? 'menu-button--active' : 'menu-button'}
<button styleName={isStarredActive ? 'menu-button-star--active' : 'menu-button'}
onClick={handleStarredButtonClick}
>
<i className='fa fa-star fa-fw' />
<span styleName='menu-button-label'>Starred</span>
</button>
<button styleName={isTrashedActive ? 'menu-button--active' : 'menu-button'}
onClick={handleTrashedButtonClick}
>
<i className='fa fa-trash fa-fw' />
<span styleName='menu-button-label'>Trash</span>
</button>
</div>
)
@@ -38,7 +44,9 @@ SideNavFilter.propTypes = {
isHomeActive: PropTypes.bool.isRequired,
handleAllNotesButtonClick: PropTypes.func.isRequired,
isStarredActive: PropTypes.bool.isRequired,
handleStarredButtonClick: PropTypes.func.isRequired
isTrashedActive: PropTypes.bool.isRequired,
handleStarredButtonClick: PropTypes.func.isRequired,
handleTrashdButtonClick: PropTypes.func.isRequired
}
export default CSSModules(SideNavFilter, styles)

View File

@@ -5,17 +5,44 @@
navButtonColor()
height 32px
padding 0 15px
font-size 14px
font-size 12px
width 100%
text-align left
overflow ellipsis
.menu-button--active
@extend .menu-button
color #e74c3c
background-color $ui-button--active-backgroundColor
color $ui-button--active-color
.menu-button-label
color $ui-text-color
&:hover
background-color $ui-button--active-backgroundColor
color #e74c3c
.menu-button-label
color $ui-text-color
&:active, &:active:hover
background-color $ui-button--active-backgroundColor
color #e74c3c
.menu-button-label
color $ui-text-color
.menu-button-star--active
@extend .menu-button
color #F9BF3B
background-color $ui-button--active-backgroundColor
.menu-button-label
color $ui-text-color
&:hover
background-color $ui-button--active-backgroundColor
color #F9BF3B
.menu-button-label
color $ui-text-color
&:active, &:active:hover
background-color $ui-button--active-backgroundColor
color #F9BF3B
.menu-button-label
color $ui-text-color
.menu-button-label
margin-left 5px
@@ -48,11 +75,31 @@
body[data-theme="dark"]
.menu-button
navDarkButtonColor()
&:active
background-color $ui-dark-button--active-backgroundColor
color $ui-dark-text-color
&:hover
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
color $ui-dark-text-color
.menu-button--active
@extend .menu-button
color #c0392b
background-color $ui-dark-button--active-backgroundColor
color $ui-dark-button--active-color
.menu-button-label
color $ui-dark-text-color
&:hover
background-color $ui-dark-button--active-backgroundColor
color #c0392b
.menu-button-label
color $ui-dark-text-color
.menu-button-star--active
color $ui-favorite-star-button-color
background-color $ui-dark-button--active-backgroundColor
.menu-button-label
color $ui-dark-text-color
&:hover
background-color $ui-dark-button--active-backgroundColor
color $ui-favorite-star-button-color
.menu-button-label
color $ui-dark-text-color

View File

@@ -96,6 +96,7 @@ class SnippetTab extends React.Component {
{!this.state.isRenaming
? <button styleName='button'
onClick={(e) => this.handleClick(e)}
onDoubleClick={(e) => this.handleRenameClick(e)}
onContextMenu={(e) => this.handleContextMenu(e)}
>
{snippet.name.trim().length > 0

View File

@@ -60,7 +60,7 @@ body[data-theme="dark"]
&:hover
background-color darken($ui-dark-button--hover-backgroundColor, 15%)
&:active
color white
color $ui-dark-text-color
background-color $ui-dark-button--active-backgroundColor
.root--active
@@ -73,7 +73,7 @@ body[data-theme="dark"]
&:hover
background-color darken($ui-dark-button--hover-backgroundColor, 15%)
&:active
color white
color $ui-dark-text-color
background-color $ui-dark-button--active-backgroundColor
.button
@@ -83,9 +83,9 @@ body[data-theme="dark"]
transition color background-color 0.15s
border-left 4px solid transparent
&:hover
color white
color $ui-dark-text-color
background-color $ui-dark-button--hover-backgroundColor
.input
background-color $ui-dark-button--hover-backgroundColor
color white
color $ui-dark-text-color

View File

@@ -14,11 +14,14 @@ import { isNumber } from 'lodash'
* @param {string} folderColor
* @param {boolean} isFolded
* @param {number} noteCount
* @param {Function} handleDrop
* @param {Function} handleDragEnter
* @param {Function} handleDragOut
* @return {React.Component}
*/
const StorageItem = ({
isActive, handleButtonClick, handleContextMenu, folderName,
folderColor, isFolded, noteCount
folderColor, isFolded, noteCount, handleDrop, handleDragEnter, handleDragLeave
}) => (
<button styleName={isActive
? 'folderList-item--active'
@@ -26,6 +29,9 @@ const StorageItem = ({
}
onClick={handleButtonClick}
onContextMenu={handleContextMenu}
onDrop={handleDrop}
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
>
<span styleName={isFolded
? 'folderList-item-name--folded' : 'folderList-item-name'
@@ -52,6 +58,8 @@ StorageItem.propTypes = {
folderName: PropTypes.string.isRequired,
folderColor: PropTypes.string,
isFolded: PropTypes.bool.isRequired,
handleDragEnter: PropTypes.func.isRequired,
handleDragLeave: PropTypes.func.isRequired,
noteCount: PropTypes.number
}

View File

@@ -13,30 +13,32 @@
text-align left
border none
overflow ellipsis
font-size 14px
font-size 12px
&:first-child
margin-top 0
&:hover
background-color $ui-button--hover-backgroundColor
color $ui-text-color
background-color alpha($ui-button--active-backgroundColor, 20%)
transition background-color 0.15s
&:active
color $ui-button--active-color
color $ui-text-color
background-color $ui-button--active-backgroundColor
.folderList-item--active
@extend .folderList-item
color $ui-button--active-color
color $ui-text-color
background-color $ui-button--active-backgroundColor
&:hover
color $ui-button--active-color
color $ui-text-color
background-color $ui-button--active-backgroundColor
.folderList-item-name
display block
flex 1
padding 0 30px
padding 0 25px
height 26px
line-height 26px
border-width 0 0 0 3px
border-width 0 0 0 2px
border-style solid
border-color transparent
overflow hidden
@@ -67,4 +69,24 @@
.folderList-item-name--folded
@extend .folderList-item-name
padding-left 14px
padding-left 12px
body[data-theme="dark"]
.folderList-item
&:hover
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
color $ui-dark-text-color
&:active
color $ui-dark-text-color
background-color $ui-dark-button--active-backgroundColor
.folderList-item--active
@extend .folderList-item
color $ui-dark-text-color
background-color $ui-dark-button--active-backgroundColor
&:active
background-color $ui-dark-button--active-backgroundColor
&:hover
color $ui-dark-text-color
background-color $ui-dark-button--active-backgroundColor

View File

@@ -0,0 +1,27 @@
/**
* @fileoverview Percentage of todo achievement.
*/
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './TodoListPercentage.styl'
/**
* @param {number} percentageOfTodo
*/
const TodoListPercentage = ({
percentageOfTodo
}) => (
<div styleName='percentageBar' style={{display: isNaN(percentageOfTodo) ? 'none' : ''}}>
<div styleName='progressBar' style={{width: `${percentageOfTodo}%`}}>
<p styleName='percentageText'>{percentageOfTodo}%</p>
</div>
</div>
)
TodoListPercentage.propTypes = {
percentageOfTodo: PropTypes.number.isRequired
}
export default CSSModules(TodoListPercentage, styles)

View File

@@ -0,0 +1,31 @@
.percentageBar
position absolute
top 58px
right: 0px
left 0px
background-color #DADFE1
width 100%
height: 15px
font-size: 12px
z-index 100
border-radius 2px
.progressBar
background-color: #6C7A89
height 15px
border-radius 2px
transition 0.3s
.percentageText
color #f4f4f4
padding: 2px 43%
body[data-theme="dark"]
.percentageBar
background-color #363A3D
.progressBar
background-color: alpha(#939395, 50%)
.percentageText
color $ui-dark-text-color

View File

@@ -54,7 +54,6 @@ body
font-family helvetica, arial, sans-serif
line-height 1.6
overflow-x hidden
user-select all
background-color $ui-noteDetail-backgroundColor
.katex
font 400 1.2em 'KaTeX_Main'
@@ -78,7 +77,6 @@ body
li
label.taskListItem
margin-left -2em
background-color white
div.math-rendered
text-align center
.math-failed
@@ -272,7 +270,7 @@ table
border-right solid 1px borderColor
themeDarkBackground = darken(#21252B, 10%)
themeDarkText = #DDDDDD
themeDarkText = #f9f9f9
themeDarkBorder = lighten(themeDarkBackground, 20%)
themeDarkPreview = $ui-dark-noteDetail-backgroundColor
themeDarkTableOdd = themeDarkPreview
@@ -290,8 +288,9 @@ body[data-theme="dark"]
background-color alpha(lighten(brandColor, 30%), 0.2) !important
code
color #EA6730
border-color darken(themeDarkBorder, 10%)
background-color lighten(themeDarkPreview, 10%)
background-color lighten(themeDarkPreview, 5%)
pre
border-color lighten(#21252B, 20%)

View File

@@ -25,6 +25,7 @@ $list-width = 250px
.result
absolute left right bottom
top $search-height
background-color $ui-noteDetail-backgroundColor
.result-nav
user-select none
@@ -89,6 +90,9 @@ body[data-theme="dark"]
.search-input
color $ui-dark-text-color
.result
background-color $ui-dark-noteList-backgroundColor
.result-nav
background-color $ui-dark-backgroundColor
label

View File

@@ -106,6 +106,11 @@ class NoteDetail extends React.Component {
let editorIndentSize = parseInt(config.editor.indentSize, 10)
if (!(editorFontSize > 0 && editorFontSize < 132)) editorIndentSize = 4
const cachedStorageList = JSON.parse(localStorage.getItem('storages'))
if (!_.isArray(cachedStorageList)) throw new Error('Target storage doesn\'t exist.')
const storage = _.find(cachedStorageList, {key: note.storage})
if (storage === undefined) throw new Error('Target storage doesn\'t exist.')
if (note.type === 'SNIPPET_NOTE') {
let tabList = note.snippets.map((snippet, index) => {
let isActive = this.state.snippetIndex === index
@@ -192,6 +197,7 @@ class NoteDetail extends React.Component {
lineNumber={config.preview.lineNumber}
indentSize={editorIndentSize}
value={note.content}
storagePath={storage.path}
/>
)
}

View File

@@ -70,7 +70,6 @@ class NoteList extends React.Component {
dateDisplay={dateDisplay}
key={key}
handleNoteClick={(e) => this.props.handleNoteClick(e, _index)}
handleNoteContextMenu={() => ''}
/>
)
})

View File

@@ -10,6 +10,7 @@ import StorageSection from './StorageSection'
import NoteList from './NoteList'
import NoteDetail from './NoteDetail'
import SideNavFilter from 'browser/components/SideNavFilter'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
require('!!style!css!stylus?sourceMap!../main/global.styl')
require('../lib/customMeta')
@@ -67,12 +68,8 @@ class FinderMain extends React.Component {
}
handleWindowBlur (e) {
let { filter } = this.state
filter.type = 'ALL'
this.setState({
search: '',
filter,
index: 0
search: ''
})
}
@@ -98,6 +95,7 @@ class FinderMain extends React.Component {
if (e.keyCode === 13) {
this.refs.detail.saveToClipboard()
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('COPY_FINDER')
hideFinder()
e.preventDefault()
}

View File

@@ -8,7 +8,7 @@ import moment from 'moment'
* @param {mixed}
* @return {string}
*/
export function getLastUpdated (date) {
export function formatDate (date) {
const m = moment(date)
if (!m.isValid()) {
throw Error('Invalid argument.')

View File

@@ -0,0 +1,33 @@
export function findNoteTitle (value) {
let splitted = value.split('\n')
let title = null
let isInsideCodeBlock = false
splitted.some((line, index) => {
let trimmedLine = line.trim()
let trimmedNextLine = splitted[index + 1] === undefined ? '' : splitted[index + 1].trim()
if (trimmedLine.match('```')) {
isInsideCodeBlock = !isInsideCodeBlock
}
if (isInsideCodeBlock === false && (trimmedLine.match(/^# +/) || trimmedNextLine.match(/^=+$/))) {
title = trimmedLine
return true
}
})
if (title === null) {
title = ''
splitted.some((line) => {
if (line.trim().length > 0) {
title = line.trim()
return true
}
})
}
return title
}
export default {
findNoteTitle
}

View File

@@ -0,0 +1,45 @@
/**
* @fileoverview Text trimmer for html.
*/
/**
* @param {string} text
* @return {string}
*/
export function decodeEntities (text) {
var entities = [
['apos', '\''],
['amp', '&'],
['lt', '<'],
['gt', '>'],
['#63', '\\?'],
['#36', '\\$']
]
for (var i = 0, max = entities.length; i < max; ++i) {
text = text.replace(new RegExp(`&${entities[i][0]};`, 'g'), entities[i][1])
}
return text
}
export function encodeEntities (text) {
const entities = [
['\'', 'apos'],
['<', 'lt'],
['>', 'gt'],
['\\?', '#63'],
['\\$', '#36']
]
entities.forEach((entity) => {
text = text.replace(new RegExp(entity[0], 'g'), `&${entity[1]};`)
})
return text
}
export default {
decodeEntities,
encodeEntities
}

View File

@@ -19,6 +19,7 @@ var md = markdownit({
linkify: true,
html: true,
xhtmlOut: true,
breaks: true,
highlight: function (str, lang) {
if (lang === 'flowchart') {
return `<pre class="flowchart">${str}</pre>`
@@ -56,6 +57,7 @@ md.use(math, {
return output
}
})
md.use(require('markdown-it-imsize'))
md.use(require('markdown-it-footnote'))
// Override task item
md.block.ruler.at('paragraph', function (state, startLine/*, endLine */) {
@@ -157,7 +159,8 @@ function strip (input) {
const markdown = {
render: function markdown (content) {
if (!_.isString(content)) content = ''
return md.render(content)
const renderedContent = md.render(content)
return md.normalizeLinkText(renderedContent)
},
strip
}

43
browser/lib/search.js Normal file
View File

@@ -0,0 +1,43 @@
import _ from 'lodash'
export default function searchFromNotes (data, search) {
let notes = data.noteMap.map((note) => note)
if (search.trim().length === 0) return []
let searchBlocks = search.split(' ')
searchBlocks.forEach((block) => {
if (block.match(/^#.+/)) {
notes = findByTag(notes, block)
} else {
notes = findByWord(notes, block)
}
})
return notes
}
function findByTag (notes, block) {
const tag = block.match(/#(.+)/)[1]
let regExp = new RegExp(_.escapeRegExp(tag), 'i')
return notes.filter((note) => {
if (!_.isArray(note.tags)) return false
return note.tags.some((_tag) => {
return _tag.match(regExp)
})
})
}
function findByWord (notes, block) {
let regExp = new RegExp(_.escapeRegExp(block), 'i')
return notes.filter((note) => {
if (_.isArray(note.tags) && note.tags.some((_tag) => {
return _tag.match(regExp)
})) {
return true
}
if (note.type === 'SNIPPET_NOTE') {
return note.description.match(regExp)
} else if (note.type === 'MARKDOWN_NOTE') {
return note.content.match(regExp)
}
return false
})
}

View File

@@ -1,8 +1,5 @@
.root
absolute top bottom right
border-width 1px 0
border-style solid
border-color $ui-borderColor
.empty
height 320px
@@ -18,7 +15,6 @@
body[data-theme="dark"]
.root
border-color $ui-dark-borderColor
background-color $ui-dark-backgroundColor
.empty-message
color $ui-dark-inactive-text-color

View File

@@ -1,7 +1,7 @@
.root
position relative
border solid 1px transparent
line-height 34px
line-height 26px
vertical-align middle
border-radius 2px
transition 0.15s
@@ -26,7 +26,7 @@
overflow ellipsis
.idle-label-name
font-size 16px
font-size 14px
padding 2px
.idle-label-name-surfix
@@ -81,7 +81,7 @@
background-color $ui-button--active-backgroundColor
color $ui-button--active-color
.search-optionList-item-name
border-left solid 4px transparent
border-left solid 2px transparent
padding 2px 5px
.search-optionList-item-name-surfix
font-size 10px

View File

@@ -0,0 +1,19 @@
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './InfoButton.styl'
const InfoButton = ({
onClick
}) => (
<button styleName='control-infoButton'
onClick={onClick}
>
<i className='fa fa-info infoButton' styleName='info-button' />
</button>
)
InfoButton.propTypes = {
onClick: PropTypes.func.isRequired
}
export default CSSModules(InfoButton, styles)

View File

@@ -0,0 +1,21 @@
.control-infoButton
float right
topBarButtonLight()
.control-infoPanel
position fixed
pointer-events none
top 50px
z-index 200
line-height normal
border-radius 2px
opacity 0
transition 0.1s
.infoButton
padding 0px
margin 15px 0
body[data-theme="dark"]
.control-infoButton
topBarButtonDark()

View File

@@ -0,0 +1,79 @@
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './InfoPanel.styl'
const InfoPanel = ({
storageName, folderName, noteLink, updatedAt, createdAt, exportAsMd, exportAsTxt
}) => (
<div className='infoPanel' styleName='control-infoButton-panel' style={{display: 'none'}}>
<div styleName='group-section'>
<div styleName='group-section-label'>
Storage
</div>
<div styleName='group-section-control'>
{storageName}
</div>
</div>
<div styleName='group-section'>
<div styleName='group-section-label'>
Folder
</div>
<div styleName='group-section-control'>
{folderName}
</div>
</div>
<div styleName='group-section'>
<div styleName='group-section-label'>
Created at
</div>
<div styleName='group-section-control'>
{createdAt}
</div>
</div>
<div styleName='group-section'>
<div styleName='group-section-label'>
Updated at
</div>
<div styleName='group-section-control'>
{updatedAt}
</div>
</div>
<div styleName='group-section'>
<div styleName='group-section-label'>
Note Link
</div>
<div styleName='group-section-control'>
<input value={noteLink} onClick={(e) => { e.target.select() }} />
</div>
</div>
<div id='export-wrap'>
<button styleName='export--enable' onClick={(e) => exportAsMd(e)}>
<i className='fa fa-file-code-o fa-fw' />
<p>.md</p>
</button>
<button styleName='export--enable' onClick={(e) => exportAsTxt(e)}>
<i className='fa fa-file-text-o fa-fw' />
<p>.txt</p>
</button>
<button styleName='export--unable'>
<i className='fa fa-file-pdf-o fa-fw' />
<p>.pdf</p>
</button>
</div>
</div>
)
InfoPanel.propTypes = {
storageName: PropTypes.string.isRequired,
folderName: PropTypes.string.isRequired,
noteLink: PropTypes.string.isRequired,
updatedAt: PropTypes.string.isRequired,
createdAt: PropTypes.string.isRequired,
exportAsMd: PropTypes.func.isRequired,
exportAsTxt: PropTypes.func.isRequired
}
export default CSSModules(InfoPanel, styles)

View File

@@ -0,0 +1,97 @@
.control-infoPanel
position fixed
pointer-events none
top 50px
z-index 200
line-height normal
border-radius 4px
opacity 0
transition 0.2s
.control-infoButton-panel
z-index 200
margin-top 45px
margin-left -210px
position absolute
padding 20px 20px 0 20px
width 340px
background-color $ui-noteList-backgroundColor
border 1px solid $border-color
.group-section
display flex
line-height 30px
font-size 13px
.group-section-label
width 70px
height 20px
text-align left
margin-right 50px
font-size 13px
color $ui-inactive-text-color
.group-section-control
flex 1
font-size 13px
color $ui-text-color
.group-section-control input
width 160px
height 25px
[id=export-wrap]
height 90px
display flex
justify-content center
margin 20px 0 10px 0
button
outline none
font-size 48px
color #A0A0A0
background-color transparent
border none
margin 0 5px
border-radius 5px
&:hover
transition 0.2s
background-color alpha($ui-button--hover-backgroundColor, 30%)
color $ui-inactive-text-color
p
font-size 13px
color #A0A0A0
font-weight light
&:hover
color $ui-inactive-text-color
.export--enable
cursor pointer
.export--unable
cursor not-allowed
body[data-theme="dark"]
.control-infoButton-panel
background-color $ui-dark-noteList-backgroundColor
border 1px solid $ui-dark-borderColor
.group-section-label
color $ui-inactive-text-color
.group-section-control
color $ui-dark-text-color
.group-section-control input
background-color alpha($ui-dark-borderColor, 80%)
color $ui-dark-text-color
[id=export-wrap]
button
color $ui-dark-inactive-text-color
&:hover
background-color alpha($ui-dark-borderColor, 20%)
color $ui-dark-text-color
p
color $ui-dark-inactive-text-color
&:hover
color $ui-dark-text-color

View File

@@ -1,27 +0,0 @@
/**
* @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

@@ -1,10 +0,0 @@
.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

@@ -2,6 +2,7 @@ import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './MarkdownNoteDetail.styl'
import MarkdownEditor from 'browser/components/MarkdownEditor'
import TodoListPercentage from 'browser/components/TodoListPercentage'
import StarButton from './StarButton'
import TagSelect from './TagSelect'
import FolderSelect from './FolderSelect'
@@ -11,6 +12,12 @@ import ee from 'browser/main/lib/eventEmitter'
import markdown from 'browser/lib/markdown'
import StatusBar from '../StatusBar'
import _ from 'lodash'
import { findNoteTitle } from 'browser/lib/findNoteTitle'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
import TrashButton from './TrashButton'
import InfoButton from './InfoButton'
import InfoPanel from './InfoPanel'
import { formatDate } from 'browser/lib/date-formatter'
const electron = require('electron')
const { remote } = electron
@@ -25,15 +32,23 @@ class MarkdownNoteDetail extends React.Component {
note: Object.assign({
title: '',
content: ''
}, props.note)
}, props.note),
isLockButtonShown: false,
isLocked: false
}
this.dispatchTimer = null
this.toggleLockButton = this.handleToggleLockButton.bind(this)
}
focus () {
this.refs.content.focus()
}
componentDidMount () {
ee.on('topbar:togglelockbutton', this.toggleLockButton)
}
componentWillReceiveProps (nextProps) {
if (nextProps.note.key !== this.props.note.key && !this.isMovingNote) {
if (this.saveQueue != null) this.saveNow()
@@ -41,7 +56,7 @@ class MarkdownNoteDetail extends React.Component {
note: Object.assign({}, nextProps.note)
}, () => {
this.refs.content.reload()
this.refs.tags.reset()
if (this.refs.tags) this.refs.tags.reset()
})
}
}
@@ -50,42 +65,34 @@ class MarkdownNoteDetail extends React.Component {
if (this.saveQueue != null) this.saveNow()
}
findTitle (value) {
let splitted = value.split('\n')
let title = null
componentDidUnmount () {
ee.off('topbar:togglelockbutton', this.toggleLockButton)
}
for (let i = 0; i < splitted.length; i++) {
let trimmedLine = splitted[i].trim()
if (trimmedLine.match(/^# .+/)) {
title = trimmedLine.substring(1, trimmedLine.length).trim()
break
getPercentageOfCompleteTodo (noteContent) {
let splitted = noteContent.split('\n')
let numberOfTodo = 0
let numberOfCompletedTodo = 0
splitted.forEach((line) => {
let trimmedLine = line.trim()
if (trimmedLine.match(/^[\+\-\*] \[\s|x\] ./)) {
numberOfTodo++
}
}
if (title == null) {
for (let i = 0; i < splitted.length; i++) {
let trimmedLine = splitted[i].trim()
if (trimmedLine.length > 0) {
title = trimmedLine
break
}
if (trimmedLine.match(/^[\+\-\*] \[x\] ./)) {
numberOfCompletedTodo++
}
if (title == null) {
title = ''
}
}
})
title = markdown.strip(title)
return title
return Math.floor(numberOfCompletedTodo / numberOfTodo * 100)
}
handleChange (e) {
let { note } = this.state
note.content = this.refs.content.value
note.tags = this.refs.tags.value
note.title = this.findTitle(note.content)
if (this.refs.tags) note.tags = this.refs.tags.value
note.title = markdown.strip(findNoteTitle(note.content))
note.updatedAt = new Date()
this.setState({
@@ -114,6 +121,7 @@ class MarkdownNoteDetail extends React.Component {
type: 'UPDATE_NOTE',
note: note
})
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('EDIT_NOTE')
})
}
@@ -152,6 +160,7 @@ class MarkdownNoteDetail extends React.Component {
handleStarButtonClick (e) {
let { note } = this.state
if (!note.isStarred) AwsMobileAnalyticsConfig.recordDynamicCustomEvent('ADD_STAR')
note.isStarred = !note.isStarred
@@ -166,23 +175,26 @@ class MarkdownNoteDetail extends React.Component {
}
handleContextButtonClick (e) {
let menu = new Menu()
menu.append(new MenuItem({
label: 'Delete',
click: (e) => this.handleDeleteMenuClick(e)
}))
menu.popup(remote.getCurrentWindow())
exportAsMd () {
ee.emit('export:save-md')
}
handleDeleteMenuClick (e) {
let index = dialog.showMessageBox(remote.getCurrentWindow(), {
type: 'warning',
message: 'Delete a note',
detail: 'This work cannot be undone.',
buttons: ['Confirm', 'Cancel']
})
if (index === 0) {
exportAsTxt () {
ee.emit('export:save-text')
}
handleTrashButtonClick (e) {
let { note } = this.state
const { isTrashed } = note
if (isTrashed) {
let dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), {
type: 'warning',
message: 'Delete a note',
detail: 'This work cannot be undone.',
buttons: ['Confirm', 'Cancel']
})
if (dialogueButtonIndex === 1) return
let { note, dispatch } = this.props
dataApi
.deleteNote(note.storage, note.key)
@@ -195,53 +207,168 @@ class MarkdownNoteDetail extends React.Component {
})
}
ee.once('list:moved', dispatchHandler)
ee.emit('list:next')
})
} else {
note.isTrashed = true
this.setState({
note
}, () => {
this.save()
})
}
ee.emit('list:next')
}
handleUndoButtonClick (e) {
let { note } = this.state
note.isTrashed = false
this.setState({
note
}, () => {
this.save()
this.refs.content.reload()
ee.emit('list:next')
})
}
handleFullScreenButton (e) {
ee.emit('editor:fullscreen')
}
handleLockButtonMouseDown (e) {
e.preventDefault()
ee.emit('editor:lock')
this.setState({ isLocked: !this.state.isLocked })
if (this.state.isLocked) this.focus()
}
getToggleLockButton () {
return this.state.isLocked ? 'fa-lock' : 'fa-unlock'
}
handleDeleteKeyDown (e) {
if (e.keyCode === 27) this.handleDeleteCancelButtonClick(e)
}
handleToggleLockButton (event, noteStatus) {
// first argument event is not used
if (this.props.config.editor.switchPreview === 'BLUR' && noteStatus === 'CODE') {
this.setState({isLockButtonShown: true})
} else {
this.setState({isLockButtonShown: false})
}
}
handleFocus (e) {
this.focus()
}
handleInfoButtonClick (e) {
const infoPanel = document.querySelector('.infoPanel')
if (infoPanel.style) infoPanel.style.display = infoPanel.style.display === 'none' ? 'inline' : 'none'
}
render () {
let { data, config } = this.props
let { data, config, location } = this.props
let { note } = this.state
let storageKey = note.storage
let folderKey = note.folder
let options = []
data.storageMap.forEach((storage, index) => {
storage.folders.forEach((folder) => {
options.push({
storage: storage,
folder: folder
})
})
})
let currentOption = options.filter((option) => option.storage.key === storageKey && option.folder.key === folderKey)[0]
const trashTopBar = <div styleName='info'>
<div styleName='info-left'>
<i styleName='undo-button'
className='fa fa-undo fa-fw'
onClick={(e) => this.handleUndoButtonClick(e)}
/>
</div>
<div styleName='info-right'>
<TrashButton onClick={(e) => this.handleTrashButtonClick(e)} />
</div>
</div>
const detailTopBar = <div styleName='info'>
<div styleName='info-left'>
<StarButton styleName='info-left-button'
onClick={(e) => this.handleStarButtonClick(e)}
isActive={note.isStarred}
/>
<div styleName='info-left-top'>
<FolderSelect styleName='info-left-top-folderSelect'
value={this.state.note.storage + '-' + this.state.note.folder}
ref='folder'
data={data}
onChange={(e) => this.handleFolderChange(e)}
/>
</div>
<TagSelect
ref='tags'
value={this.state.note.tags}
onChange={(e) => this.handleChange(e)}
/>
<TodoListPercentage
percentageOfTodo={this.getPercentageOfCompleteTodo(note.content)}
/>
</div>
<div styleName='info-right'>
{(() => {
const faClassName = `fa ${this.getToggleLockButton()}`
const lockButtonComponent =
<button styleName='control-lockButton'
onFocus={(e) => this.handleFocus(e)}
onMouseDown={(e) => this.handleLockButtonMouseDown(e)}
>
<i className={faClassName} styleName='lock-button' />
<span styleName='control-lockButton-tooltip'>
{this.state.isLocked ? 'Unlock' : 'Lock'}
</span>
</button>
return (
this.state.isLockButtonShown ? lockButtonComponent : ''
)
})()}
<TrashButton onClick={(e) => this.handleTrashButtonClick(e)} />
<button styleName='control-fullScreenButton'
onMouseDown={(e) => this.handleFullScreenButton(e)}
>
<i className='fa fa-expand' styleName='fullScreen-button' />
</button>
<InfoButton
onClick={(e) => this.handleInfoButtonClick(e)}
/>
<InfoPanel
storageName={currentOption.storage.name}
folderName={currentOption.folder.name}
noteLink={`[${note.title}](${location.query.key})`}
updatedAt={formatDate(note.updatedAt)}
createdAt={formatDate(note.createdAt)}
exportAsMd={this.exportAsMd}
exportAsTxt={this.exportAsTxt}
/>
</div>
</div>
return (
<div className='NoteDetail'
style={this.props.style}
styleName='root'
>
<div styleName='info'>
<div styleName='info-left'>
<StarButton styleName='info-left-button'
onClick={(e) => this.handleStarButtonClick(e)}
isActive={note.isStarred}
/>
<div styleName='info-left-top'>
<FolderSelect styleName='info-left-top-folderSelect'
value={this.state.note.storage + '-' + this.state.note.folder}
ref='folder'
data={data}
onChange={(e) => this.handleFolderChange(e)}
/>
</div>
<TagSelect
ref='tags'
value={this.state.note.tags}
onChange={(e) => this.handleChange(e)}
/>
</div>
<div styleName='info-right'>
<button styleName='info-right-button'
onClick={(e) => this.handleContextButtonClick(e)}
>
<i className='fa fa-ellipsis-v' />
</button>
</div>
</div>
{location.pathname === '/trashed' ? trashTopBar : detailTopBar}
<div styleName='body'>
<MarkdownEditor
@@ -249,6 +376,7 @@ class MarkdownNoteDetail extends React.Component {
styleName='body-noteEditor'
config={config}
value={this.state.note.content}
storageKey={this.state.note.storage}
onChange={(e) => this.handleChange(e)}
ignorePreviewPointerEvents={this.props.ignorePreviewPointerEvents}
/>

View File

@@ -9,6 +9,29 @@
background-color $ui-noteDetail-backgroundColor
box-shadow $note-detail-box-shadow
.lock-button
padding-bottom 3px
.control-lockButton
topBarButtonLight()
.control-lockButton-tooltip
tooltip()
position fixed
pointer-events none
top 50px
z-index 200
padding 5px
line-height normal
border-radius 2px
opacity 0
transition 0.1s
.control-fullScreenButton
float right
padding 0 0 2px 0
topBarButtonLight()
.body
absolute left right
left $note-detail-left-margin
@@ -24,3 +47,12 @@ body[data-theme="dark"]
border-color $ui-dark-borderColor
background-color $ui-dark-noteDetail-backgroundColor
box-shadow none
.control-lockButton
topBarButtonDark()
.control-lockButton-tooltip
darkTooltip()
.control-fullScreenButton
topBarButtonDark()

View File

@@ -15,36 +15,36 @@ $info-margin-under-border = 27px
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
line-height 26px
display flex
align-items center
justify-content center
border-radius 3px
.info-left-button
width 34px
height 34px
navButtonColor()
color $ui-favorite-star-button-color
font-size 14px
line-height 0
margin 13px 2px
padding 0
border-radius 17px
&:hover .info-right-button-tooltip
&:hover .info-left-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
color $ui-button--color
.info-right
position absolute
@@ -54,20 +54,26 @@ $info-margin-under-border = 27px
bottom 1px
padding-left 30px
.info-right-button
.undo-button
width 34px
height 34px
border-radius 17px
font-size 14px
margin 13px 7px
padding 0
margin 15px 7px
border none
color $ui-button-color
display flex
align-items center
justify-content center
fill $ui-button-color
background-color transparent
cursor pointer
&:active
border-color $ui-button--active-backgroundColor
&:hover
opacity 1
background-color $ui-button--hover-backgroundColor
background-color alpha($ui-button--hover-backgroundColor, 60%)
.control-lockButton-tooltip
opacity 1
body[data-theme="dark"]
.info
@@ -89,10 +95,5 @@ body[data-theme="dark"]
.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
.undo-button
topBarButtonDark()

View File

@@ -15,6 +15,12 @@ import StatusBar from '../StatusBar'
import context from 'browser/lib/context'
import ConfigManager from 'browser/main/lib/ConfigManager'
import _ from 'lodash'
import { findNoteTitle } from 'browser/lib/findNoteTitle'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
import TrashButton from './TrashButton'
import InfoButton from './InfoButton'
import InfoPanel from './InfoPanel'
import { formatDate } from 'browser/lib/date-formatter'
function pass (name) {
switch (name) {
@@ -51,7 +57,7 @@ class SnippetNoteDetail extends React.Component {
}
componentWillReceiveProps (nextProps) {
if (nextProps.note.key !== this.props.note.key) {
if (nextProps.note.key !== this.props.note.key && !this.isMovingNote) {
if (this.saveQueue != null) this.saveNow()
let nextNote = Object.assign({
description: ''
@@ -66,7 +72,7 @@ class SnippetNoteDetail extends React.Component {
snippets.forEach((snippet, index) => {
this.refs['code-' + index].reload()
})
this.refs.tags.reset()
if (this.refs.tags) this.refs.tags.reset()
})
}
}
@@ -75,41 +81,13 @@ class SnippetNoteDetail extends React.Component {
if (this.saveQueue != null) this.saveNow()
}
findTitle (value) {
let splitted = value.split('\n')
let title = null
for (let i = 0; i < splitted.length; i++) {
let trimmedLine = splitted[i].trim()
if (trimmedLine.match(/^# .+/)) {
title = trimmedLine.substring(1, trimmedLine.length).trim()
break
}
}
if (title == null) {
for (let i = 0; i < splitted.length; i++) {
let trimmedLine = splitted[i].trim()
if (trimmedLine.length > 0) {
title = trimmedLine
break
}
}
if (title == null) {
title = ''
}
}
return title
}
handleChange (e) {
let { note } = this.state
note.tags = this.refs.tags.value
if (this.refs.tags) note.tags = this.refs.tags.value
note.description = this.refs.description.value
note.updatedAt = new Date()
note.title = this.findTitle(note.description)
note.title = findNoteTitle(note.description)
this.setState({
note
@@ -137,6 +115,7 @@ class SnippetNoteDetail extends React.Component {
type: 'UPDATE_NOTE',
note: note
})
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('EDIT_NOTE')
})
}
@@ -175,6 +154,7 @@ class SnippetNoteDetail extends React.Component {
handleStarButtonClick (e) {
let { note } = this.state
if (!note.isStarred) AwsMobileAnalyticsConfig.recordDynamicCustomEvent('ADD_STAR')
note.isStarred = !note.isStarred
@@ -189,21 +169,18 @@ class SnippetNoteDetail extends React.Component {
}
handleContextButtonClick (e) {
context.popup([{
label: 'Delete',
click: (e) => this.handleDeleteMenuClick(e)
}])
}
handleTrashButtonClick (e) {
let { note } = this.state
const { isTrashed } = note
handleDeleteMenuClick (e) {
let index = dialog.showMessageBox(remote.getCurrentWindow(), {
type: 'warning',
message: 'Delete a note',
detail: 'This work cannot be undone.',
buttons: ['Confirm', 'Cancel']
})
if (index === 0) {
if (isTrashed) {
let dialogueButtonIndex = dialog.showMessageBox(remote.getCurrentWindow(), {
type: 'warning',
message: 'Delete a note',
detail: 'This work cannot be undone.',
buttons: ['Confirm', 'Cancel']
})
if (dialogueButtonIndex === 1) return
let { note, dispatch } = this.props
dataApi
.deleteNote(note.storage, note.key)
@@ -216,9 +193,34 @@ class SnippetNoteDetail extends React.Component {
})
}
ee.once('list:moved', dispatchHandler)
ee.emit('list:next')
})
} else {
note.isTrashed = true
this.setState({
note
}, () => {
this.save()
})
}
ee.emit('list:next')
}
handleUndoButtonClick (e) {
let { note } = this.state
note.isTrashed = false
this.setState({
note
}, () => {
this.save()
ee.emit('list:next')
})
}
handleFullScreenButton (e) {
ee.emit('editor:fullscreen')
}
handleTabPlusButtonClick (e) {
@@ -250,15 +252,15 @@ class SnippetNoteDetail extends React.Component {
}
deleteSnippetByIndex (index) {
let snippets = this.state.note.snippets.slice()
const snippets = this.state.note.snippets.slice()
snippets.splice(index, 1)
this.state.note.snippets = snippets
let snippetIndex = this.state.snippetIndex >= snippets.length
const note = Object.assign({}, this.state.note, {snippets})
const snippetIndex = this.state.snippetIndex >= snippets.length
? snippets.length - 1
: this.state.snippetIndex
this.setState({
note: this.state.note,
snippetIndex
this.setState({ note, snippetIndex }, () => {
this.save()
this.refs['code-' + this.state.snippetIndex].reload()
})
}
@@ -459,10 +461,27 @@ class SnippetNoteDetail extends React.Component {
this.refs['code-' + this.state.snippetIndex].focus()
}
handleInfoButtonClick (e) {
const infoPanel = document.querySelector('.infoPanel')
if (infoPanel.style) infoPanel.style.display = infoPanel.style.display === 'none' ? 'inline' : 'none'
}
showWarning () {
dialog.showMessageBox(remote.getCurrentWindow(), {
type: 'warning',
message: 'Sorry!',
detail: 'md/text import is available only a markdown note.',
buttons: ['OK']
})
}
render () {
let { data, config } = this.props
let { data, config, location } = this.props
let { note } = this.state
let storageKey = note.storage
let folderKey = note.folder
let editorFontSize = parseInt(config.editor.fontSize, 10)
if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14
let editorIndentSize = parseInt(config.editor.indentSize, 10)
@@ -517,41 +536,79 @@ class SnippetNoteDetail extends React.Component {
</div>
})
let options = []
data.storageMap.forEach((storage, index) => {
storage.folders.forEach((folder) => {
options.push({
storage: storage,
folder: folder
})
})
})
let currentOption = options.filter((option) => option.storage.key === storageKey && option.folder.key === folderKey)[0]
const trashTopBar = <div styleName='info'>
<div styleName='info-left'>
<i styleName='undo-button'
className='fa fa-undo fa-fw'
onClick={(e) => this.handleUndoButtonClick(e)}
/>
</div>
<div styleName='info-right'>
<TrashButton onClick={(e) => this.handleTrashButtonClick(e)} />
</div>
</div>
const detailTopBar = <div styleName='info'>
<div styleName='info-left'>
<StarButton styleName='info-left-button'
onClick={(e) => this.handleStarButtonClick(e)}
isActive={note.isStarred}
/>
<div styleName='info-left-top'>
<FolderSelect styleName='info-left-top-folderSelect'
value={this.state.note.storage + '-' + this.state.note.folder}
ref='folder'
data={data}
onChange={(e) => this.handleFolderChange(e)}
/>
</div>
<TagSelect
ref='tags'
value={this.state.note.tags}
onChange={(e) => this.handleChange(e)}
/>
</div>
<div styleName='info-right'>
<TrashButton onClick={(e) => this.handleTrashButtonClick(e)} />
<button styleName='control-fullScreenButton'
onMouseDown={(e) => this.handleFullScreenButton(e)}
>
<i className='fa fa-expand' styleName='fullScreen-button' />
</button>
<InfoButton
onClick={(e) => this.handleInfoButtonClick(e)}
/>
<InfoPanel
storageName={currentOption.storage.name}
folderName={currentOption.folder.name}
noteLink={`[${note.title}](${location.query.key})`}
updatedAt={formatDate(note.updatedAt)}
createdAt={formatDate(note.createdAt)}
exportAsMd={this.showWarning}
exportAsTxt={this.showWarning}
/>
</div>
</div>
return (
<div className='NoteDetail'
style={this.props.style}
styleName='root'
onKeyDown={(e) => this.handleKeyDown(e)}
>
<div styleName='info'>
<div styleName='info-left'>
<StarButton styleName='info-left-button'
onClick={(e) => this.handleStarButtonClick(e)}
isActive={note.isStarred}
/>
<div styleName='info-left-top'>
<FolderSelect styleName='info-left-top-folderSelect'
value={this.state.note.storage + '-' + this.state.note.folder}
ref='folder'
data={data}
onChange={(e) => this.handleFolderChange(e)}
/>
</div>
<TagSelect
ref='tags'
value={this.state.note.tags}
onChange={(e) => this.handleChange(e)}
/>
</div>
<div styleName='info-right'>
<button styleName='info-right-button'
onClick={(e) => this.handleContextButtonClick(e)}
>
<i className='fa fa-ellipsis-v' />
</button>
</div>
</div>
{location.pathname === '/trashed' ? trashTopBar : detailTopBar}
<div styleName='body'>
<div styleName='description'>

View File

@@ -22,6 +22,7 @@
height 80px
.body .description textarea
outline none
display block
height 100%
width 100%
@@ -62,12 +63,14 @@
button
navButtonColor()
height 24px
border-width 0 1px 0 0
border-style solid
border-color $ui-borderColor
&:active .update-icon
color white
.control-fullScreenButton
float right
padding 0 0 2px 0
topBarButtonLight()
body[data-theme="dark"]
.root
border-color $ui-dark-borderColor
@@ -79,7 +82,7 @@ body[data-theme="dark"]
.body .description textarea
background-color $ui-dark-noteDetail-backgroundColor
color white
color $ui-dark-text-color
.tabList
background-color $ui-button--active-backgroundColor
@@ -93,3 +96,10 @@ body[data-theme="dark"]
.override
button
border-color $ui-dark-borderColor
&:hover
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
transition 0.15s
color $ui-dark-text-color
.control-fullScreenButton
topBarButtonDark()

View File

@@ -2,19 +2,46 @@
left 7px
top 0
padding 0
color alpha($ui-favorite-star-button-color, 60%)
&:hover
.icon
transform rotate(-72deg)
.tooltip
opacity 1
transition 0.15s
background-color alpha($ui-button--active-backgroundColor, 40%)
color $ui-favorite-star-button-color
&:active
transition 0.15s
background-color alpha($ui-button--active-backgroundColor, 40%)
color $ui-favorite-star-button-color
.root--active
@extend .root
color $ui-favorite-star-button-color
&:hover
transition 0.15s
color $ui-favorite-star-button-color
.icon
transform rotate(-72deg)
background-color alpha($ui-button--active-backgroundColor, 40%)
&:active
transition 0.15s
color $ui-favorite-star-button-color
background-color alpha($ui-button--active-backgroundColor, 40%)
.icon
transition transform 0.15s
body[data-theme="dark"]
.root
&:hover
transition 0.15s
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
color $ui-favorite-star-button-color
&:active
transition 0.15s
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
color $ui-favorite-star-button-color
.root--active
@extend .root
color $ui-favorite-star-button-color
&:hover
transition 0.15s
color $ui-favorite-star-button-color
background-color alpha($ui-dark-button--active-backgroundColor, 20%)

View File

@@ -2,6 +2,7 @@ import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './TagSelect.styl'
import _ from 'lodash'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
class TagSelect extends React.Component {
constructor (props) {
@@ -56,6 +57,7 @@ class TagSelect extends React.Component {
}
submitTag () {
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('ADD_TAG')
let { value } = this.props
let newTag = this.refs.newTag.value.trim().replace(/ +/g, '_')
@@ -107,7 +109,7 @@ class TagSelect extends React.Component {
<span styleName='tag'
key={tag}
>
<span styleName='tag-label'>{tag}</span>
<span styleName='tag-label'>#{tag}</span>
<button styleName='tag-removeButton'
onClick={(e) => this.handleTagRemoveButtonClick(tag)(e)}
>

View File

@@ -1,7 +1,7 @@
.root
display inline-block
top 19px
user-select none
height 23px
vertical-align middle
width 300px
overflow-x scroll
@@ -12,12 +12,11 @@
.tag
display inline-block
margin 0 2px
padding-left 10px
vertical-align middle
margin 1px 3px
padding 0
height 20px
background-color $ui-tag-backgroundColor
border-radius 20px
background-color alpha($ui-tag-backgroundColor, 10%)
border-radius 3px
overflow hidden
clearfix()
@@ -39,9 +38,9 @@
padding-right 4px
.tag-label
font-size 12px
font-weight bold
color: #FFFFFF
font-size 11px
font-weight 600
color: alpha($ui-text-color, 80%)
float left
height 20px
line-height 20px
@@ -49,41 +48,18 @@
.newTag
display inline-block
margin 0 2px
margin 2px 0 15px 2px
vertical-align middle
height 24px
height 18px
box-sizing borde-box
border none
border-bottom $ui-border
background-color transparent
outline none
padding 0 4px
&:focus
border-color $ui-input--focus-borderColor = #369DCD
&:disabled
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"]
.icon
color $ui-dark-button-color
.tag
background-color $ui-dark-tag-backgroundColor
background-color alpha($ui-dark-tag-backgroundColor, 60%)
.tag-removeButton
border-color $ui-button--focus-borderColor
@@ -94,17 +70,6 @@ body[data-theme="dark"]
color $ui-dark-text-color
.newTag
border-color $ui-dark-borderColor
border-color none
background-color transparent
color $ui-dark-text-color
&:focus
border-color $ui-input--focus-borderColor = #369DCD
&:disabled
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
color $ui-dark-text-color

View File

@@ -0,0 +1,19 @@
import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './TrashButton.styl'
const TrashButton = ({
onClick
}) => (
<button styleName='control-trashButton'
onClick={(e) => onClick(e)}
>
<i className='fa fa-trash trashButton' styleName='info-button' />
</button>
)
TrashButton.propTypes = {
onClick: PropTypes.func.isRequired
}
export default CSSModules(TrashButton, styles)

View File

@@ -0,0 +1,11 @@
.control-trashButton
float right
topBarButtonLight()
.trashButton
padding 0px
margin 15px 0
body[data-theme="dark"]
.control-trashButton
topBarButtonDark()

View File

@@ -17,7 +17,7 @@ class Detail extends React.Component {
this.refs.root != null && this.refs.root.focus()
}
this.deleteHandler = () => {
this.refs.root != null && this.refs.root.handleDeleteMenuClick()
this.refs.root != null && this.refs.root.handleTrashButtonClick()
}
}

View File

@@ -12,6 +12,8 @@ import ConfigManager from 'browser/main/lib/ConfigManager'
import modal from 'browser/main/lib/modal'
import InitModal from 'browser/main/modals/InitModal'
import mixpanel from 'browser/main/lib/mixpanel'
import mobileAnalytics from 'browser/main/lib/AwsMobileAnalyticsConfig'
import eventEmitter from 'browser/main/lib/eventEmitter'
function focused () {
mixpanel.track('MAIN_FOCUSED')
@@ -21,14 +23,23 @@ class Main extends React.Component {
constructor (props) {
super(props)
if (process.env.NODE_ENV === 'production') {
mobileAnalytics.initAwsMobileAnalytics()
}
let { config } = props
this.state = {
isRightSliderFocused: false,
listWidth: config.listWidth,
navWidth: config.navWidth,
isLeftSliderFocused: false
isLeftSliderFocused: false,
fullScreen: false,
noteDetailWidth: 0,
mainBodyWidth: 0
}
this.toggleFullScreen = () => this.handleFullScreenButton()
}
getChildContext () {
@@ -63,11 +74,13 @@ class Main extends React.Component {
}
})
eventEmitter.on('editor:fullscreen', this.toggleFullScreen)
window.addEventListener('focus', focused)
}
componentWillUnmount () {
window.removeEventListener('focus', focused)
eventEmitter.off('editor:fullscreen', this.toggleFullScreen)
}
handleLeftSlideMouseDown (e) {
@@ -144,6 +157,34 @@ class Main extends React.Component {
}
}
handleFullScreenButton (e) {
this.setState({ fullScreen: !this.state.fullScreen }, () => {
const noteDetail = document.querySelector('.NoteDetail')
const noteList = document.querySelector('.NoteList')
const mainBody = document.querySelector('#main-body')
if (this.state.fullScreen) {
this.hideLeftLists(noteDetail, noteList, mainBody)
} else {
this.showLeftLists(noteDetail, noteList, mainBody)
}
})
}
hideLeftLists (noteDetail, noteList, mainBody) {
this.state.noteDetailWidth = noteDetail.style.left
this.state.mainBodyWidth = mainBody.style.left
noteDetail.style.left = '0px'
mainBody.style.left = '0px'
noteList.style.display = 'none'
}
showLeftLists (noteDetail, noteList, mainBody) {
noteDetail.style.left = this.state.noteDetailWidth
mainBody.style.left = this.state.mainBodyWidth
noteList.style.display = 'inline'
}
render () {
let { config } = this.props
@@ -173,6 +214,7 @@ class Main extends React.Component {
</div>
}
<div styleName={config.isSideNavFolded ? 'body--expanded' : 'body'}
id='main-body'
ref='body'
style={{left: config.isSideNavFolded ? 44 : this.state.navWidth}}
>

View File

@@ -13,10 +13,12 @@
absolute top bottom
top -2px
width 0
z-index 0
.slider-right
@extend .slider
width 1px
z-index 0
.slider--active
@extend .slider

View File

@@ -17,34 +17,42 @@ $control-height = 30px
.control-sortBy
flex 1
padding-left 25px
padding-left 22px
.control-sortBy-select
margin-left 0
font-size 12px
appearance: none;
margin-left 3px
color $ui-inactive-text-color
padding 0
border none
background-color transparent
font-size 10px
outline none
cursor pointer
font-size 11px
&:hover
transition 0.2s
color $ui-text-color
.control-button-area
margin-right 12px
.control-button
width 25px
padding 0
background-color transparent
border none
color $ui-inactive-text-color
color alpha($ui-inactive-text-color, 60%)
transition 0.15s
&:active, &:active:hover
color $ui-active-color
color $ui-inactive-text-color
&:hover
color $ui-text-color
color $ui-inactive-text-color
.control-button--active
@extend .control-button
color $ui-active-color
color $ui-inactive-text-color
&:hover
color $ui-active-color
color $ui-inactive-text-color
.list
absolute left right bottom
@@ -56,15 +64,21 @@ body[data-theme="dark"]
border-color $ui-dark-borderColor
background-color $ui-dark-noteList-backgroundColor
.control
background-color $ui-dark-noteList-backgroundColor
.control
background-color $ui-dark-noteList-backgroundColor
border-color $ui-dark-borderColor
.control-sortBy-select
&:hover
transition 0.2s
color $ui-dark-text-color
.control-button
color $ui-dark-inactive-text-color
&:hover
color $ui-dark-text-color
.control-button--active
color $ui-dark-text-color
&:active
color $ui-dark-text-color

View File

@@ -8,6 +8,11 @@ import dataApi from 'browser/main/lib/dataApi'
import ConfigManager from 'browser/main/lib/ConfigManager'
import NoteItem from 'browser/components/NoteItem'
import NoteItemSimple from 'browser/components/NoteItemSimple'
import searchFromNotes from 'browser/lib/search'
import fs from 'fs'
import { hashHistory } from 'react-router'
import markdown from 'browser/lib/markdown'
import { findNoteTitle } from 'browser/lib/findNoteTitle'
const { remote } = require('electron')
const { Menu, MenuItem, dialog } = remote
@@ -38,6 +43,11 @@ class NoteList extends React.Component {
this.focusHandler = () => {
this.refs.list.focus()
}
this.alertIfSnippetHandler = () => {
this.alertIfSnippet()
}
this.importFromFileHandler = this.importFromFile.bind(this)
this.jumpNoteByHash = this.jumpNoteByHashHandler.bind(this)
this.state = {
}
@@ -48,6 +58,9 @@ class NoteList extends React.Component {
ee.on('list:next', this.selectNextNoteHandler)
ee.on('list:prior', this.selectPriorNoteHandler)
ee.on('list:focus', this.focusHandler)
ee.on('list:isMarkdownNote', this.alertIfSnippetHandler)
ee.on('import:file', this.importFromFileHandler)
ee.on('list:jump', this.jumpNoteByHash)
}
componentWillReceiveProps (nextProps) {
@@ -66,6 +79,9 @@ class NoteList extends React.Component {
ee.off('list:next', this.selectNextNoteHandler)
ee.off('list:prior', this.selectPriorNoteHandler)
ee.off('list:focus', this.focusHandler)
ee.off('list:isMarkdownNote', this.alertIfSnippetHandler)
ee.off('import:file', this.importFromFileHandler)
ee.off('list:jump', this.jumpNoteByHash)
}
componentDidUpdate (prevProps) {
@@ -158,6 +174,31 @@ class NoteList extends React.Component {
ee.emit('list:moved')
}
jumpNoteByHashHandler (event, noteHash) {
// first argument event isn't used.
if (this.notes === null || this.notes.length === 0) {
return
}
const { router } = this.context
const { location } = this.props
let targetIndex = _.findIndex(this.notes, (note) => {
return note.storage + '-' + note.key === noteHash
})
if (targetIndex < 0) targetIndex = 0
router.push({
pathname: location.pathname,
query: {
key: this.notes[targetIndex].storage + '-' + this.notes[targetIndex].key
}
})
ee.emit('list:moved')
}
handleNoteListKeyDown (e) {
if (e.metaKey || e.ctrlKey) return true
@@ -189,6 +230,7 @@ class NoteList extends React.Component {
getNotes () {
let { data, params, location } = this.props
let { router } = this.context
if (location.pathname.match(/\/home/)) {
return data.noteMap.map((note) => note)
@@ -199,6 +241,19 @@ class NoteList extends React.Component {
.map((uniqueKey) => data.noteMap.get(uniqueKey))
}
if (location.pathname.match(/\/searched/)) {
const searchInputText = document.getElementsByClassName('searchInput')[0].value
if (searchInputText === '') {
router.push('/home')
}
return searchFromNotes(this.props.data, searchInputText)
}
if (location.pathname.match(/\/trashed/)) {
return data.trashedSet.toJS()
.map((uniqueKey) => data.noteMap.get(uniqueKey))
}
let storageKey = params.storageKey
let folderKey = params.folderKey
let storage = data.storageMap.get(storageKey)
@@ -234,49 +289,6 @@ class NoteList extends React.Component {
})
}
handleNoteContextMenu (e, uniqueKey) {
let menu = new Menu()
menu.append(new MenuItem({
label: 'Delete Note',
click: (e) => this.handleDeleteNote(e, uniqueKey)
}))
menu.popup()
}
handleDeleteNote (e, uniqueKey) {
let index = dialog.showMessageBox(remote.getCurrentWindow(), {
type: 'warning',
message: 'Delete a note',
detail: 'This work cannot be undone.',
buttons: ['Confirm', 'Cancel']
})
if (index === 0) {
let { dispatch, location } = this.props
let splitted = uniqueKey.split('-')
let storageKey = splitted.shift()
let noteKey = splitted.shift()
dataApi
.deleteNote(storageKey, noteKey)
.then((data) => {
let dispatchHandler = () => {
dispatch({
type: 'DELETE_NOTE',
storageKey: data.storageKey,
noteKey: data.noteKey
})
}
if (location.query.key === uniqueKey) {
ee.once('list:moved', dispatchHandler)
ee.emit('list:next')
} else {
dispatchHandler()
}
})
}
}
handleSortByChange (e) {
let { dispatch } = this.props
@@ -305,8 +317,73 @@ class NoteList extends React.Component {
})
}
alertIfSnippet () {
let { location } = this.props
const targetIndex = _.findIndex(this.notes, (note) => {
return `${note.storage}-${note.key}` === location.query.key
})
if (this.notes[targetIndex].type === 'SNIPPET_NOTE') {
dialog.showMessageBox(remote.getCurrentWindow(), {
type: 'warning',
message: 'Sorry!',
detail: 'md/text import is available only a markdown note.',
buttons: ['OK', 'Cancel']
})
}
}
handleDragStart (e, note) {
const noteData = JSON.stringify(note)
e.dataTransfer.setData('note', noteData)
}
importFromFile () {
const { dispatch, location } = this.props
const options = {
filters: [
{ name: 'Documents', extensions: ['md', 'txt'] }
],
properties: ['openFile', 'multiSelections']
}
const targetIndex = _.findIndex(this.notes, (note) => {
return note !== null && `${note.storage}-${note.key}` === location.query.key
})
const storageKey = this.notes[targetIndex].storage
const folderKey = this.notes[targetIndex].folder
dialog.showOpenDialog(remote.getCurrentWindow(), options, (filepaths) => {
if (filepaths === undefined) return
filepaths.forEach((filepath) => {
fs.readFile(filepath, (err, data) => {
if (err) throw Error('File reading error: ', err)
const content = data.toString()
const newNote = {
content: content,
folder: folderKey,
title: markdown.strip(findNoteTitle(content)),
type: 'MARKDOWN_NOTE'
}
dataApi.createNote(storageKey, newNote)
.then((note) => {
dispatch({
type: 'UPDATE_NOTE',
note: note
})
hashHistory.push({
pathname: location.pathname,
query: {key: `${note.storage}-${note.key}`}
})
})
})
})
})
}
render () {
let { location, notes, config } = this.props
let { location, notes, config, dispatch } = this.props
let sortFunc = config.sortBy === 'CREATED_AT'
? sortByCreatedAt
: config.sortBy === 'ALPHABETICAL'
@@ -314,6 +391,10 @@ class NoteList extends React.Component {
: sortByUpdatedAt
this.notes = notes = this.getNotes()
.sort(sortFunc)
.filter((note) => {
// this is for the trash box
if (note.isTrashed !== true || location.pathname === '/trashed') return true
})
let noteList = notes
.map(note => {
@@ -337,7 +418,7 @@ class NoteList extends React.Component {
dateDisplay={dateDisplay}
key={key}
handleNoteClick={this.handleNoteClick.bind(this)}
handleNoteContextMenu={this.handleNoteContextMenu.bind(this)}
handleDragStart={this.handleDragStart.bind(this)}
/>
)
}
@@ -348,7 +429,7 @@ class NoteList extends React.Component {
note={note}
key={key}
handleNoteClick={this.handleNoteClick.bind(this)}
handleNoteContextMenu={this.handleNoteContextMenu.bind(this)}
handleDragStart={this.handleDragStart.bind(this)}
/>
)
})
@@ -360,7 +441,7 @@ class NoteList extends React.Component {
>
<div styleName='control'>
<div styleName='control-sortBy'>
Sort by
<i className='fa fa-bolt' />
<select styleName='control-sortBy-select'
value={config.sortBy}
onChange={(e) => this.handleSortByChange(e)}
@@ -370,22 +451,24 @@ class NoteList extends React.Component {
<option value='ALPHABETICAL'>Alphabetical</option>
</select>
</div>
<button styleName={config.listStyle === 'DEFAULT'
? 'control-button--active'
: 'control-button'
}
onClick={(e) => this.handleListStyleButtonClick(e, 'DEFAULT')}
>
<i className='fa fa-th-large' />
</button>
<button styleName={config.listStyle === 'SMALL'
? 'control-button--active'
: 'control-button'
}
onClick={(e) => this.handleListStyleButtonClick(e, 'SMALL')}
>
<i className='fa fa-list-ul' />
</button>
<div styleName='control-button-area'>
<button styleName={config.listStyle === 'DEFAULT'
? 'control-button--active'
: 'control-button'
}
onClick={(e) => this.handleListStyleButtonClick(e, 'DEFAULT')}
>
<i className='fa fa-th-large' />
</button>
<button styleName={config.listStyle === 'SMALL'
? 'control-button--active'
: 'control-button'
}
onClick={(e) => this.handleListStyleButtonClick(e, 'SMALL')}
>
<i className='fa fa-list-ul' />
</button>
</div>
</div>
<div styleName='list'
ref='list'

View File

@@ -1,7 +1,7 @@
.root
absolute top left bottom
width $sideNav-width
background-color $ui-backgroundColor
background-color #f9f9f9
user-select none
color $ui-text-color
@@ -10,11 +10,16 @@
.top-menu
navButtonColor()
height $topBar-height - 1
height $topBar-height
padding 0 15px
font-size 14px
font-size 12px
width 100%
text-align left
&:hover
color $ui-text-color
&:active, &:active:hover
color $ui-text-color
background-color alpha($ui-button--active-backgroundColor, 20%)
.top-menu-label
margin-left 5px
@@ -110,10 +115,16 @@ body[data-theme="dark"]
.top-menu
navDarkButtonColor()
&:active
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
&:hover
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
.storageList-empty
color $ui-dark-inactive-text-color
.navToggle
navDarkButtonColor()
&:hover
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
transition 0.15s
color $ui-dark-text-color

View File

@@ -7,6 +7,7 @@ import CreateFolderModal from 'browser/main/modals/CreateFolderModal'
import RenameFolderModal from 'browser/main/modals/RenameFolderModal'
import dataApi from 'browser/main/lib/dataApi'
import StorageItemChild from 'browser/components/StorageItem'
import eventEmitter from 'browser/main/lib/eventEmitter'
const { remote } = require('electron')
const { Menu, MenuItem, dialog } = remote
@@ -131,8 +132,54 @@ class StorageItem extends React.Component {
}
}
handleDragEnter (e) {
e.dataTransfer.setData('defaultColor', e.target.style.backgroundColor)
e.target.style.backgroundColor = 'rgba(129, 130, 131, 0.08)'
}
handleDragLeave (e) {
e.target.style.opacity = '1'
e.target.style.backgroundColor = e.dataTransfer.getData('defaultColor')
}
handleDrop (e, storage, folder, dispatch, location) {
e.target.style.opacity = '1'
e.target.style.backgroundColor = e.dataTransfer.getData('defaultColor')
const noteData = JSON.parse(e.dataTransfer.getData('note'))
const newNoteData = Object.assign({}, noteData, {storage: storage, folder: folder.key})
if (folder.key === noteData.folder) return
dataApi
.createNote(storage.key, newNoteData)
.then((note) => {
dataApi
.deleteNote(noteData.storage, noteData.key)
.then((data) => {
let dispatchHandler = () => {
dispatch({
type: 'DELETE_NOTE',
storageKey: data.storageKey,
noteKey: data.noteKey
})
}
eventEmitter.once('list:moved', dispatchHandler)
eventEmitter.emit('list:next')
})
.catch((err) => {
console.error(err)
})
dispatch({
type: 'UPDATE_NOTE',
note: note
})
hashHistory.push({
pathname: location.pathname,
query: {key: `${note.storage}-${note.key}`}
})
})
}
render () {
let { storage, location, isFolded, data } = this.props
let { storage, location, isFolded, data, dispatch } = this.props
let { folderNoteMap } = data
let folderList = storage.folders.map((folder) => {
let isActive = !!(location.pathname.match(new RegExp('\/storages\/' + storage.key + '\/folders\/' + folder.key)))
@@ -151,6 +198,9 @@ class StorageItem extends React.Component {
folderColor={folder.color}
isFolded={isFolded}
noteCount={noteCount}
handleDrop={(e) => this.handleDrop(e, storage, folder, dispatch, location)}
handleDragEnter={this.handleDragEnter}
handleDragLeave={this.handleDragLeave}
/>
)
})

View File

@@ -1,84 +1,79 @@
.root
width 100%
user-select none
padding-top 20px
.header
position relative
height 26px
height 25px
width 100%
margin-bottom 5px
transition 0.15s
&:hover
background-color $ui-button--hover-backgroundColor
&:active
.header-toggleButton
.header-addFolderButton
color white
&:active
color $ui-active-color
.header--active
@extend .header
.header-info
color $ui-button--active-color
background-color $ui-button--active-backgroundColor
margin-bottom 5px
background-color $ui-button--active-backgroundColor
transition color background-color 0.15s
.header--active
.header-toggleButton
color $ui-text-color
.header--active
.header-info
color $ui-text-color
.header--active
.header-addFolderButton
color white
&:active
&:hover
&:hover:active
color white
color $ui-text-color
.header-toggleButton
navButtonColor()
position absolute
left 0
width 25px
height 26px
height 25px
padding 0
border none
color $ui-inactive-text-color
background-color transparent
border-radius 50%
&:hover
transition 0.2s
background-color alpha($ui-button--active-backgroundColor, 40%)
color $ui-text-color
&:active
color $ui-active-color
.header-info
navButtonColor()
display block
width 100%
height 30px
padding-left 25px
height 25px
padding-left 23px
padding-right 10px
line-height 26px
line-height 22px
cursor pointer
font-size 14px
font-size 13px
border none
overflow ellipsis
text-align left
background-color transparent
color $ui-inactive-text-color
&:active
color $ui-button--active-color
background-color $ui-button--active-backgroundColor
background-color alpha($ui-button--active-backgroundColor, 20%)
.header-info-path
font-size 10px
margin 0 5px
.header-addFolderButton
navButtonColor()
position absolute
right 0
width 25px
height 26px
height 25px
padding 0
border none
color $ui-inactive-text-color
background-color transparent
margin-right 5px
border-radius 50%
&:hover
transition 0.2s
background-color alpha($ui-button--active-backgroundColor, 40%)
color $ui-text-color
&:active
color $ui-active-color
.root--folded
@extend .root
@@ -108,16 +103,50 @@
margin 0 5px
body[data-theme="dark"]
.header-toggleButton
.header-addFolderButton
color $ui-dark-inactive-text-color
&:hover
color $ui-dark-text-color
&:active
color $ui-dark-active-color
.header--active
background-color $ui-dark-button--active-backgroundColor
transition color background-color 0.15s
.header--active
.header-toggleButton
.header-addFolderButton
color white
color $ui-dark-text-color
.header--active
.header-info
color $ui-dark-text-color
background-color $ui-dark-button--active-backgroundColor
&:active
color white
color $ui-dark-text-color
background-color $ui-dark-button--active-backgroundColor
.header--active
.header-addFolderButton
color $ui-dark-text-color
.header-toggleButton
&:hover
transition 0.2s
color $ui-dark-text-color
background-color alpha($ui-dark-button--active-backgroundColor, 60%)
&:active, &:active:hover
color $ui-dark-text-color
background-color $ui-dark-button--active-backgroundColor
.header-info
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
&:hover
transition 0.2s
color $ui-dark-text-color
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
&:active, &:active:hover
color $ui-dark-text-color
background-color $ui-dark-button--active-backgroundColor
.header-addFolderButton
&:hover
transition 0.2s
color $ui-dark-text-color
background-color alpha($ui-dark-button--active-backgroundColor, 60%)
&:active, &:active:hover
color $ui-dark-text-color
background-color $ui-dark-button--active-backgroundColor

View File

@@ -33,12 +33,18 @@ class SideNav extends React.Component {
})
}
handleTrashedButtonClick (e) {
let { router } = this.context
router.push('/trashed')
}
render () {
let { data, location, config, dispatch } = this.props
let isFolded = config.isSideNavFolded
let isHomeActive = !!location.pathname.match(/^\/home$/)
let isStarredActive = !!location.pathname.match(/^\/starred$/)
let isTrashedActive = !!location.pathname.match(/^\/trashed$/)
let storageList = data.storageMap.map((storage, key) => {
return <StorageItem
@@ -62,8 +68,8 @@ class SideNav extends React.Component {
<button styleName='top-menu'
onClick={(e) => this.handleMenuButtonClick(e)}
>
<i className='fa fa-navicon fa-fw' />
<span styleName='top-menu-label'>Menu</span>
<i className='fa fa-wrench fa-fw' />
<span styleName='top-menu-label'>Preferences</span>
</button>
</div>
@@ -72,7 +78,9 @@ class SideNav extends React.Component {
isHomeActive={isHomeActive}
handleAllNotesButtonClick={(e) => this.handleHomeButtonClick(e)}
isStarredActive={isStarredActive}
isTrashedActive={isTrashedActive}
handleStarredButtonClick={(e) => this.handleStarredButtonClick(e)}
handleTrashedButtonClick={(e) => this.handleTrashedButtonClick(e)}
/>
<div styleName='storageList'>

View File

@@ -4,9 +4,7 @@
absolute bottom left right
height $statusBar-height
background-color $ui-noteDetail-backgroundColor
border-top $ui-border
display flex
box-shadow $note-detail-box-shadow
.blank
flex 1
@@ -24,9 +22,6 @@
.zoom
navButtonColor()
height 24px
border-width 0 1px
border-style solid
border-color $ui-borderColor
.update
navButtonColor()
@@ -48,6 +43,10 @@ body[data-theme="dark"]
.zoom
border-color $ui-dark-borderColor
&:hover
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
transition 0.15s
color $ui-dark-text-color
.help
navButtonColor()

View File

@@ -2,13 +2,12 @@ import React, { PropTypes } from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './StatusBar.styl'
import ZoomManager from 'browser/main/lib/ZoomManager'
import LastUpdatedString from '../Detail/LastUpdatedString'
const electron = require('electron')
const { remote, ipcRenderer } = electron
const { Menu, MenuItem, dialog } = remote
const zoomOptions = [0.8, 0.9, 1, 1.1, 1.2, 1.3]
const zoomOptions = [0.8, 0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0]
class StatusBar extends React.Component {
updateApp () {
@@ -68,8 +67,6 @@ class StatusBar extends React.Component {
</button>
: null
}
<LastUpdatedString date={this.props.date} />
</div>
)
}

View File

@@ -19,37 +19,37 @@ $control-height = 34px
.control-search
height 32px
width 1px
flex 1
background-color white
position relative
.control-search-icon
absolute top bottom left
line-height 32px
width 35px
color $ui-inactive-text-color
background-color $ui-noteList-backgroundColor
.control-search-input
display block
absolute top bottom right
left 30px
width 100%
padding-left 12px
background-color $ui-noteList-backgroundColor
input
width 100%
height 100%
outline none
border none
color $ui-text-color
font-size 16px
padding-bottom 2px
background-color $ui-noteList-backgroundColor
.control-search-optionList
position fixed
z-index 200
width 275px
height 175px
width 500px
height 250px
overflow-y auto
background-color $modal-background
border-radius 2px
box-shadow 2px 2px 10px gray
border-none
box-shadow 0 0 1px rgba(76,86,103,.25), 0 2px 18px rgba(31,37,50,.32)
.control-search-optionList-item
height 50px
@@ -59,10 +59,10 @@ $control-height = 34px
cursor pointer
overflow ellipsis
&:hover
background-color alpha($ui-active-color, 10%)
background-color alpha(#D4D4D4, 30%)
.control-search-optionList-item-folder
border-left 4px solid transparent
border-left 2px solid transparent
padding 2px 5px
color $ui-text-color
overflow ellipsis
@@ -91,9 +91,7 @@ $control-height = 34px
width 32px
height $control-height - 2
navButtonColor()
border $ui-border
border-radius 32px
font-size 14px
font-size 16px
line-height 28px
padding 0
&:active
@@ -131,6 +129,7 @@ body[data-theme="dark"]
background-color $ui-dark-noteList-backgroundColor
.control-search-input
background-color $ui-dark-noteList-backgroundColor
input
background-color $ui-dark-noteList-backgroundColor
color $ui-dark-text-color
@@ -144,7 +143,7 @@ body[data-theme="dark"]
.control-search-optionList-item
border-color $ui-dark-borderColor
&:hover
background-color lighten($ui-dark-button--hover-backgroundColor, 15%)
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
.control-search-optionList-item-folder
color $ui-dark-text-color
.control-search-optionList-item-folder-surfix
@@ -159,10 +158,14 @@ body[data-theme="dark"]
color $ui-inactive-text-color
.control-newPostButton
colorDarkDefaultButton()
color $ui-inactive-text-color
border-color $ui-dark-borderColor
background-color $ui-dark-noteList-backgroundColor
&:hover
transition 0.15s
color $ui-dark-text-color
&:active
background-color alpha($ui-dark-button--active-backgroundColor, 20%)
border-color $ui-dark-button--active-backgroundColor
.control-newPostButton-tooltip

View File

@@ -9,6 +9,9 @@ import ee from 'browser/main/lib/eventEmitter'
import ConfigManager from 'browser/main/lib/ConfigManager'
import dataApi from 'browser/main/lib/dataApi'
const { remote } = require('electron')
const { dialog } = remote
const OSX = window.process.platform === 'darwin'
class TopBar extends React.Component {
@@ -18,24 +21,40 @@ class TopBar extends React.Component {
this.state = {
search: '',
searchOptions: [],
searchPopupOpen: false
isSearching: false
}
this.newNoteHandler = () => {
this.handleNewPostButtonClick()
}
this.focusSearchHandler = () => {
this.handleOnSearchFocus()
}
}
componentDidMount () {
ee.on('top:new-note', this.newNoteHandler)
ee.on('top:focus-search', this.focusSearchHandler)
}
componentWillUnmount () {
ee.off('top:new-note', this.newNoteHandler)
ee.off('top:focus-search', this.focusSearchHandler)
}
handleNewPostButtonClick (e) {
let { config } = this.props
let { config, location } = this.props
if (location.pathname === '/trashed') {
dialog.showMessageBox(remote.getCurrentWindow(), {
type: 'warning',
message: 'Cannot create new note',
detail: 'You cannot create new note in trash box.',
buttons: ['OK']
})
return
}
switch (config.ui.defaultNote) {
case 'MARKDOWN_NOTE':
@@ -81,79 +100,17 @@ class TopBar extends React.Component {
}
handleSearchChange (e) {
let { router } = this.context
router.push('/searched')
this.setState({
search: this.refs.searchInput.value
})
}
getOptions () {
let { data } = this.props
let { search } = this.state
let notes = data.noteMap.map((note) => note)
if (search.trim().length === 0) return []
let searchBlocks = search.split(' ')
searchBlocks.forEach((block) => {
if (block.match(/^!#.+/)) {
let tag = block.match(/^!#(.+)/)[1]
let regExp = new RegExp(_.escapeRegExp(tag), 'i')
notes = notes
.filter((note) => {
if (!_.isArray(note.tags)) return false
return note.tags.some((_tag) => {
return _tag.match(regExp)
})
})
} else if (block.match(/^!.+/)) {
let block = block.match(/^!(.+)/)[1]
let regExp = new RegExp(_.escapeRegExp(block), 'i')
notes = notes.filter((note) => {
if (!_.isArray(note.tags) || !note.tags.some((_tag) => {
return _tag.match(regExp)
})) {
return true
}
if (note.type === 'SNIPPET_NOTE') {
return !note.description.match(regExp)
} else if (note.type === 'MARKDOWN_NOTE') {
return !note.content.match(regExp)
}
return false
})
} else if (block.match(/^#.+/)) {
let tag = block.match(/#(.+)/)[1]
let regExp = new RegExp(_.escapeRegExp(tag), 'i')
notes = notes
.filter((note) => {
if (!_.isArray(note.tags)) return false
return note.tags.some((_tag) => {
return _tag.match(regExp)
})
})
} else {
let regExp = new RegExp(_.escapeRegExp(block), 'i')
notes = notes.filter((note) => {
if (_.isArray(note.tags) && note.tags.some((_tag) => {
return _tag.match(regExp)
})) {
return true
}
if (note.type === 'SNIPPET_NOTE') {
return note.description.match(regExp)
} else if (note.type === 'MARKDOWN_NOTE') {
return note.content.match(regExp)
}
return false
})
}
})
return notes
}
handleOptionClick (uniqueKey) {
return (e) => {
this.setState({
searchPopupOpen: false
isSearching: false
}, () => {
let { location } = this.props
hashHistory.push({
@@ -168,7 +125,7 @@ class TopBar extends React.Component {
handleSearchFocus (e) {
this.setState({
searchPopupOpen: true
isSearching: true
})
}
handleSearchBlur (e) {
@@ -185,7 +142,7 @@ class TopBar extends React.Component {
}
if (!isStillFocused) {
this.setState({
searchPopupOpen: false
isSearching: false
})
}
}
@@ -244,29 +201,16 @@ class TopBar extends React.Component {
})
}
handleOnSearchFocus () {
if (this.state.isSearching) {
this.refs.search.childNodes[0].blur()
} else {
this.refs.search.childNodes[0].focus()
}
}
render () {
let { config, style, data } = this.props
let searchOptionList = this.getOptions()
.map((note) => {
let storage = data.storageMap.get(note.storage)
let folder = _.find(storage.folders, {key: note.folder})
return <div styleName='control-search-optionList-item'
key={note.storage + '-' + note.key}
onClick={(e) => this.handleOptionClick(note.storage + '-' + note.key)(e)}
>
<div styleName='control-search-optionList-item-folder'
style={{borderColor: folder.color}}>
{folder.name}
<span styleName='control-search-optionList-item-folder-surfix'>in {storage.name}</span>
</div>
{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-file-text-o' />
}&nbsp;
{note.title}
</div>
})
return (
<div className='TopBar'
styleName={config.isSideNavFolded ? 'root--expanded' : 'root'}
@@ -274,7 +218,6 @@ class TopBar extends React.Component {
>
<div styleName='control'>
<div styleName='control-search'>
<i styleName='control-search-icon' className='fa fa-search fa-fw' />
<div styleName='control-search-input'
onFocus={(e) => this.handleSearchFocus(e)}
onBlur={(e) => this.handleSearchBlur(e)}
@@ -287,15 +230,8 @@ class TopBar extends React.Component {
onChange={(e) => this.handleSearchChange(e)}
placeholder='Search'
type='text'
className='searchInput'
/>
{this.state.searchPopupOpen &&
<div styleName='control-search-optionList'>
{searchOptionList.length > 0
? searchOptionList
: <div styleName='control-search-optionList-empty'>Empty List</div>
}
</div>
}
</div>
{this.state.search > 0 &&
<button styleName='left-search-clearButton'
@@ -308,7 +244,7 @@ class TopBar extends React.Component {
</div>
<button styleName='control-newPostButton'
onClick={(e) => this.handleNewPostButtonClick(e)}>
<i className='fa fa-plus' />
<i className='fa fa-pencil-square-o' />
<span styleName='control-newPostButton-tooltip'>
Make a Note {OSX ? '⌘' : '^'} + n
</span>

View File

@@ -1,6 +1,6 @@
global-reset()
DEFAULT_FONTS = 'Lato', helvetica, arial, sans-serif
DEFAULT_FONTS = 'OpenSans', helvetica, arial, sans-serif
html, body
width 100%
@@ -11,7 +11,7 @@ body
font-family DEFAULT_FONTS
color textColor
font-size fontSize
font-weight 400
font-weight 200
button, input, select, textarea
font-family DEFAULT_FONTS

View File

@@ -23,6 +23,16 @@ document.addEventListener('dragover', function (e) {
e.stopPropagation()
})
document.addEventListener('click', function (e) {
const className = e.target.className
if (!className && typeof (className) !== 'string') return
const isInfoButton = className.includes('infoButton')
const isInfoPanel = e.target.offsetParent.className.includes('infoPanel')
if (isInfoButton || isInfoPanel) return
const infoPanel = document.querySelector('.infoPanel')
if (infoPanel) infoPanel.style.display = 'none'
})
let el = document.getElementById('content')
const history = syncHistoryWithStore(hashHistory, store)
@@ -50,6 +60,8 @@ ReactDOM.render((
<IndexRedirect to='/home' />
<Route path='home' />
<Route path='starred' />
<Route path='searched' />
<Route path='trashed' />
<Route path='storages'>
<IndexRedirect to='/home' />
<Route path=':storageKey'>

View File

@@ -0,0 +1,41 @@
const AWS = require('aws-sdk')
const AMA = require('aws-sdk-mobile-analytics')
const ConfigManager = require('browser/main/lib/ConfigManager')
AWS.config.region = 'us-east-1'
if (process.env.NODE_ENV === 'production' && ConfigManager.default.get().amaEnabled) {
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'us-east-1:xxxxxxxxxxxxxxxxxxxxxxxxx'
})
const mobileAnalyticsClient = new AMA.Manager({
appId: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
appTitle: 'xxxxxxxxxx'
})
}
function initAwsMobileAnalytics () {
if (process.env.NODE_ENV !== 'production' || !ConfigManager.default.get().amaEnabled) return
AWS.config.credentials.get((err) => {
if (!err) {
console.log('Cognito Identity ID: ' + AWS.config.credentials.identityId)
}
})
recordStaticCustomEvent()
}
function recordDynamicCustomEvent (type) {
if (process.env.NODE_ENV !== 'production' || !ConfigManager.default.get().amaEnabled) return
mobileAnalyticsClient.recordEvent(type)
}
function recordStaticCustomEvent () {
if (process.env.NODE_ENV !== 'production' || !ConfigManager.default.get().amaEnabled) return
mobileAnalyticsClient.recordEvent('UI_COLOR_THEME', {
uiColorTheme: ConfigManager.default.get().ui.theme
})
}
module.exports = {
initAwsMobileAnalytics,
recordDynamicCustomEvent
}

View File

@@ -1,6 +1,7 @@
import _ from 'lodash'
const OSX = global.process.platform === 'darwin'
const win = global.process.platform === 'win32'
const electron = require('electron')
const { ipcRenderer } = electron
const consts = require('browser/lib/consts')
@@ -14,6 +15,7 @@ export const DEFAULT_CONFIG = {
navWidth: 200,
sortBy: 'UPDATED_AT', // 'CREATED_AT', 'UPDATED_AT', 'APLHABETICAL'
listStyle: 'DEFAULT', // 'DEFAULT', 'SMALL'
amaEnabled: true,
hotkey: {
toggleFinder: OSX ? 'Cmd + Alt + S' : 'Super + Alt + S',
toggleMain: OSX ? 'Cmd + Alt + L' : 'Super + Alt + E'
@@ -24,18 +26,18 @@ export const DEFAULT_CONFIG = {
defaultNote: 'ALWAYS_ASK' // 'ALWAYS_ASK', 'SNIPPET_NOTE', 'MARKDOWN_NOTE'
},
editor: {
theme: 'default',
theme: 'base16-light',
keyMap: 'sublime',
fontSize: '14',
fontFamily: 'Monaco, Consolas',
fontFamily: win ? 'Segoe UI' : 'Monaco, Consolas',
indentType: 'space',
indentSize: '2',
switchPreview: 'BLUR' // Available value: RIGHTCLICK, BLUR
},
preview: {
fontSize: '14',
fontFamily: 'Lato',
codeBlockTheme: 'elegant',
fontFamily: win ? 'Segoe UI' : 'Lato',
codeBlockTheme: 'dracula',
lineNumber: true
}
}

View File

@@ -0,0 +1,36 @@
const fs = require('fs')
const path = require('path')
const _ = require('lodash')
const sander = require('sander')
/**
* @description To copy an image and return the path.
* @param {String} filePath
* @param {String} storageKey
* @return {String} an image path
*/
function copyImage (filePath, storageKey) {
return new Promise((resolve, reject) => {
try {
const cachedStorageList = JSON.parse(localStorage.getItem('storages'))
if (!_.isArray(cachedStorageList)) throw new Error('Target storage doesn\'t exist.')
const storage = _.find(cachedStorageList, {key: storageKey})
if (storage === undefined) throw new Error('Target storage doesn\'t exist.')
const targetStorage = storage
const inputImage = fs.createReadStream(filePath)
const imageExt = path.extname(filePath)
const imageName = Math.random().toString(36).slice(-16)
const basename = `${imageName}${imageExt}`
const imageDir = path.join(targetStorage.path, 'images')
if (!fs.existsSync(imageDir)) fs.mkdirSync(imageDir)
const outputImage = fs.createWriteStream(path.join(imageDir, basename))
inputImage.pipe(outputImage)
resolve(basename)
} catch (e) {
return reject(e)
}
})
}
module.exports = copyImage

View File

@@ -10,6 +10,7 @@ function validateInput (input) {
input.tags = input.tags.filter((tag) => _.isString(tag) && tag.trim().length > 0)
if (!_.isString(input.title)) input.title = ''
input.isStarred = !!input.isStarred
input.isTrashed = !!input.isTrashed
switch (input.type) {
case 'MARKDOWN_NOTE':

View File

@@ -41,7 +41,7 @@ function init () {
.then((notes) => {
let unknownCount = 0
notes.forEach((note) => {
if (!storage.folders.some((folder) => note.folder === folder.key)) {
if (note && !storage.folders.some((folder) => note.folder === folder.key)) {
unknownCount++
storage.folders.push({
key: note.folder,

View File

@@ -28,7 +28,6 @@ function resolveStorageNotes (storage) {
return data
} catch (err) {
console.error(notePath)
throw err
}
})

View File

@@ -21,6 +21,10 @@ function validateInput (input) {
validatedInput.isStarred = !!input.isStarred
}
if (input.isTrashed != null) {
validatedInput.isTrashed = !!input.isTrashed
}
validatedInput.type = input.type
switch (input.type) {
case 'MARKDOWN_NOTE':
@@ -101,6 +105,7 @@ function updateNote (storageKey, noteKey, input) {
noteData.createdAt = new Date()
noteData.updatedAt = new Date()
noteData.isStarred = false
noteData.isTrashed = false
noteData.tags = []
}

View File

@@ -15,6 +15,9 @@ class ModalBase extends React.Component {
close () {
if (modalBase != null) modalBase.setState({component: null, componentProps: null, isHidden: true})
// Toggle overflow style on NoteList
let list = document.querySelector('.NoteList__list___browser-main-NoteList-')
list.style.overflow = 'auto'
}
render () {
@@ -37,7 +40,9 @@ let modalBase = ReactDOM.render(<ModalBase />, el)
export function openModal (component, props) {
if (modalBase == null) { return }
// Hide scrollbar by removing overflow when modal opens
let list = document.querySelector('.NoteList__list___browser-main-NoteList-')
list.style.overflow = 'hidden'
document.body.setAttribute('data-modal', 'open')
modalBase.setState({component: component, componentProps: props, isHidden: false})
}

View File

@@ -4,6 +4,8 @@ import styles from './CreateFolderModal.styl'
import dataApi from 'browser/main/lib/dataApi'
import store from 'browser/main/store'
import consts from 'browser/lib/consts'
import ModalEscButton from 'browser/components/ModalEscButton'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
class CreateFolderModal extends React.Component {
constructor (props) {
@@ -47,6 +49,7 @@ class CreateFolderModal extends React.Component {
}
confirm () {
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('ADD_FOLDER')
if (this.state.name.trim().length > 0) {
let { storage } = this.props
let input = {
@@ -77,11 +80,7 @@ class CreateFolderModal extends React.Component {
<div styleName='header'>
<div styleName='title'>Create new folder</div>
</div>
<button styleName='close' onClick={(e) => this.handleCloseButtonClick(e)}>
<div styleName='close-mark'>X</div>
<div styleName='close-text'>esc</div>
</button>
<ModalEscButton handleEscButtonClick={(e) => this.handleCloseButtonClick(e)} />
<div styleName='control'>
<div styleName='control-folder'>
<div styleName='control-folder-label'>Folder name</div>
@@ -95,7 +94,7 @@ class CreateFolderModal extends React.Component {
<button styleName='control-confirmButton'
onClick={(e) => this.handleConfirmButtonClick(e)}
>
Create Folder
Create
</button>
</div>
</div>

View File

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

View File

@@ -1,6 +1,5 @@
import React, { PropTypes } from 'react'
import ReactDOM from 'react-dom'
import store from '../store'
const electron = require('electron')
const ipc = electron.ipcRenderer
@@ -26,7 +25,6 @@ export default class DeleteArticleModal extends React.Component {
}
handleYesButtonClick (e) {
// store.dispatch(destroyArticle(this.props.articleKey))
this.props.close()
}

View File

@@ -5,6 +5,7 @@ import dataApi from 'browser/main/lib/dataApi'
import store from 'browser/main/store'
import { hashHistory } from 'react-router'
import _ from 'lodash'
import ModalEscButton from 'browser/components/ModalEscButton'
const CSON = require('@rokt33r/season')
const path = require('path')
@@ -41,10 +42,6 @@ class InitModal extends React.Component {
}
}
handleCloseButtonClick (e) {
this.props.close()
}
handlePathChange (e) {
this.setState({
path: e.target.value
@@ -106,7 +103,7 @@ class InitModal extends React.Component {
} else {
return dataApi
.createFolder(data.storage.key, {
color: '#6AA5E9',
color: '#1278BD',
name: 'Default'
})
.then((_data) => {
@@ -125,12 +122,24 @@ class InitModal extends React.Component {
notes: data.notes
})
let defaultMarkdownNote = dataApi
let defaultSnippetNote = dataApi
.createNote(data.storage.key, {
type: 'MARKDOWN_NOTE',
type: 'SNIPPET_NOTE',
folder: data.storage.folders[0].key,
title: 'Welcome to Boostnote :)',
content: '# Welcome to Boostnote :)\nThis is a markdown note.\n\nClick to edit this note.'
title: 'Snippet note example',
description: 'Snippet note example\nYou can store a series of snippets as a single note, like Gist.',
snippets: [
{
name: 'example.html',
mode: 'html',
content: '<html>\n<body>\n<h1 id=\'hello\'>Enjoy Boostnote!</h1>\n</body>\n</html>'
},
{
name: 'example.js',
mode: 'javascript',
content: 'var boostnote = document.getElementById(\'enjoy\').innerHTML\n\nconsole.log(boostnote)'
}
]
})
.then((note) => {
store.dispatch({
@@ -138,24 +147,12 @@ class InitModal extends React.Component {
note: note
})
})
let defaultSnippetNote = dataApi
let defaultMarkdownNote = dataApi
.createNote(data.storage.key, {
type: 'SNIPPET_NOTE',
type: 'MARKDOWN_NOTE',
folder: data.storage.folders[0].key,
title: 'Snippet note example',
description: 'Snippet note example\nYou can store a series of snippet as a single note like Gist.',
snippets: [
{
name: 'example.html',
mode: 'html',
content: '<html>\n<body>\n<h1 id=\'hello\'>Hello World</h1>\n</body>\n</html>'
},
{
name: 'example.js',
mode: 'javascript',
content: 'var html = document.getElementById(\'hello\').innerHTML\n\nconsole.log(html)'
}
]
title: 'Welcome to Boostnote!',
content: '# Welcome to Boostnote! \n### _Click to edit this note._\n\n---\n\nBoostnote is an *open source* note-taking app. \nRepository is published on [GitHub](https://github.com/BoostIO/Boostnote), and tweeting everyday on [@Boostnoteapp](https://twitter.com/boostnoteapp)!\n\n## Features \n- [x] No Internet and Registration Required. \n- [ ] Quick search and copy the content of note. `macOS: Cmd + Alt + S / windows: Ctrl + Alt + S` \n- [ ] Markdown & Snippet note. \n- [ ] Available for `vim` and `emacs` mode. \n- [ ] Choose your favorite theme on UI, Editor and Code Block! \n--- \n\n- Copy Codeblock on Makrdown Preview.\n```javascript\nvar boostnote = document.getElementById(\'enjoy\').innerHTML\n\nconsole.log(boostnote)\n```'
})
.then((note) => {
store.dispatch({
@@ -187,12 +184,6 @@ class InitModal extends React.Component {
})
}
handleKeyDown (e) {
if (e.keyCode === 27) {
this.props.close()
}
}
render () {
if (this.state.isLoading) {
return <div styleName='root--loading'>
@@ -209,15 +200,13 @@ class InitModal extends React.Component {
<div styleName='header'>
<div styleName='header-title'>Initialize Storage</div>
</div>
<button styleName='closeButton'
onClick={(e) => this.handleCloseButtonClick(e)}
>Close</button>
<ModalEscButton handleEscButtonClick={(e) => this.handleCloseButtonClick(e)} />
<div styleName='body'>
<div styleName='body-welcome'>
Welcome you!
Welcome!
</div>
<div styleName='body-description'>
Boostnote will use this directory as a default storage.
Please select a directory for Boostnote storage.
</div>
<div styleName='body-path'>
<input styleName='body-path-input'

View File

@@ -22,17 +22,6 @@
border-bottom solid 1px $ui-borderColor
color $ui-text-color
.closeButton
position absolute
top 10px
right 10px
height 30px
padding 0 25px
border $ui-border
border-radius 2px
color $ui-text-color
colorDefaultButton()
.body
padding 30px

View File

@@ -4,6 +4,8 @@ import styles from './NewNoteModal.styl'
import dataApi from 'browser/main/lib/dataApi'
import { hashHistory } from 'react-router'
import ee from 'browser/main/lib/eventEmitter'
import ModalEscButton from 'browser/components/ModalEscButton'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
class NewNoteModal extends React.Component {
constructor (props) {
@@ -22,6 +24,8 @@ class NewNoteModal extends React.Component {
}
handleMarkdownNoteButtonClick (e) {
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('ADD_MARKDOWN')
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('ADD_ALLNOTE')
let { storage, folder, dispatch, location } = this.props
dataApi
.createNote(storage, {
@@ -52,6 +56,8 @@ class NewNoteModal extends React.Component {
}
handleSnippetNoteButtonClick (e) {
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('ADD_SNIPPET')
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('ADD_ALLNOTE')
let { storage, folder, dispatch, location } = this.props
dataApi
@@ -102,10 +108,7 @@ class NewNoteModal extends React.Component {
<div styleName='header'>
<div styleName='title'>Make a Note</div>
</div>
<button styleName='closeButton'
onClick={(e) => this.handleCloseButtonClick(e)}
>Close</button>
<ModalEscButton handleEscButtonClick={(e) => this.handleCloseButtonClick(e)} />
<div styleName='control'>
<button styleName='control-button'
onClick={(e) => this.handleMarkdownNoteButtonClick(e)}
@@ -116,7 +119,7 @@ class NewNoteModal extends React.Component {
className='fa fa-file-text-o'
/><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'>This format is for creating text documents. Checklists, code blocks and Latex blocks are available.</span>
</button>
<button styleName='control-button'
@@ -128,7 +131,7 @@ class NewNoteModal extends React.Component {
className='fa fa-code'
/><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 for creating code snippets. Multiple snippets can be grouped into a single note.
</span>
</button>

View File

@@ -13,17 +13,6 @@
border-bottom solid 1px $ui-borderColor
color $ui-text-color
.closeButton
position absolute
top 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
@@ -64,17 +53,12 @@ body[data-theme="dark"]
border-color $ui-dark-borderColor
color $ui-dark-text-color
.closeButton
border-color $ui-dark-borderColor
color $ui-dark-text-color
colorDarkDefaultButton()
.control-button
border-color $ui-dark-borderColor
color $ui-dark-text-color
background-color transparent
&:focus
colorPrimaryButton()
colorDarkPrimaryButton()
.description
color $ui-inactive-text-color

View File

@@ -32,14 +32,20 @@
.group-section-control
flex 1
.group-section-control select
outline none
border 1px solid $ui-borderColor
background-color transparent
.group-section-control-input
height 30px
vertical-align middle
width 400px
font-size $tab--button-font-size
border solid 1px $border-color
border-radius $tab--input-border-radius
border-radius 2px
padding 0 5px
outline none
&:disabled
background-color $ui-input--disabled-backgroundColor
@@ -64,7 +70,7 @@
.group-control-leftButton
colorDefaultButton()
border none
border-radius 5px
border-radius 2px
font-size $tab--button-font-size
height $tab--button-height
padding 0 15px
@@ -74,17 +80,17 @@
float right
colorPrimaryButton()
border none
border-radius $tab--button-border-radius
border-radius 2px
font-size $tab--button-font-size
height $tab--button-height
padding 0 15px
height 35px
width 100px
margin-right 10px
.group-hint
border $ui-border
padding 10px 15px
margin 15px 0
border-radius 5px
border-radius 2px
background-color $ui-backgroundColor
color $ui-inactive-text-color
ul
@@ -98,10 +104,17 @@
margin-left: 10px
font-size: 12px
.code-mirror
width 400px
height 120px
margin 5px 0
font-size 12px
colorDarkControl()
border-color $ui-dark-borderColor
background-color $ui-dark-backgroundColor
color $ui-dark-text-color
body[data-theme="dark"]
.root
color $ui-dark-text-color

View File

@@ -138,6 +138,8 @@ class HotkeyTab extends React.Component {
<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>
<li><code>Control</code> (or <code>Ctrl</code> for short)</li>
<li><code>Shift</code></li>
</ul>
</div>
}

View File

@@ -1,6 +1,9 @@
import React from 'react'
import CSSModules from 'browser/lib/CSSModules'
import styles from './InfoTab.styl'
import ConfigManager from 'browser/main/lib/ConfigManager'
import store from 'browser/main/store'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
const electron = require('electron')
const { shell, remote } = electron
@@ -11,6 +14,7 @@ class InfoTab extends React.Component {
super(props)
this.state = {
config: this.props.config
}
}
@@ -19,6 +23,28 @@ class InfoTab extends React.Component {
e.preventDefault()
}
handleConfigChange (e) {
const newConfig = { amaEnabled: this.refs.amaEnabled.checked }
this.setState({ config: newConfig })
}
handleSaveButtonClick (e) {
let newConfig = {
amaEnabled: this.state.config.amaEnabled
}
ConfigManager.set(newConfig)
store.dispatch({
type: 'SET_CONFIG',
config: newConfig
})
if (!newConfig.amaEnabled) {
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('DISABLE_AMA')
}
}
render () {
return (
<div styleName='root'>
@@ -30,30 +56,56 @@ class InfoTab extends React.Component {
<div styleName='icon-right'>
<div styleName='appId'>Boostnote {appVersion}</div>
<div styleName='description'>
A simple markdown/snippet note app for developer.
An open source note-taking app made for programmers just like you.
</div>
</div>
</div>
<div styleName='clear' />
<div styleName='madeBy'>Made by&nbsp;
<a href='http://maisin.co/'
onClick={(e) => this.handleLinkClick(e)}
>MAISIN&CO.</a></div>
<div styleName='copyright'>Copyright 2017 MAISIN&CO. All rights reserved.</div>
</div>
<ul styleName='list'>
<li>
The codes of this app is published under GPLv3 license.
</li>
<li>
Any kinds of feedback, creating a new issue or a pull request, would be welcomed.
</li>
<li>
Issue Tracker : <a href='https://github.com/BoostIO/Boostnote/issues'
<a href='https://boostnote.io'
onClick={(e) => this.handleLinkClick(e)}
>https://github.com/BoostIO/Boostnote/issues</a>
>Website</a>
</li>
<li>
<a href='https://boostnote.paintory.com/'
onClick={(e) => this.handleLinkClick(e)}
>Boostnote Shop</a> : Products are shipped to all over the world 🌏
</li>
<li>
<a href='https://salt.bountysource.com/teams/boostnote'
onClick={(e) => this.handleLinkClick(e)}
>Donate via Bountysource</a> : Thank you for your support 🎉
</li>
<li>
<a href='https://github.com/BoostIO/Boostnote/issues'
onClick={(e) => this.handleLinkClick(e)}
>GitHub Issues</a> : We'd love to hear your feedback 🙌
</li>
<li>
<a href='https://github.com/BoostIO/Boostnote/blob/master/docs/build.md'
onClick={(e) => this.handleLinkClick(e)}
>Development</a> : Development configurations for Boostnote 🚀
</li>
<li styleName='cc'>
Copyright (C) 2017 Maisin&Co.
</li>
<li styleName='cc'>
License: GPL v3
</li>
</ul>
<hr />
<div styleName='policy'>Data collection policy</div>
<p>We collect only the number of DAU for Boostnote and DO NOT collect any detail information</p>
<p>such as your note content. You can see how it works on <a href='https://github.com/BoostIO/Boostnote' onClick={(e) => this.handleLinkClick(e)}>GitHub</a>.</p>
<p>These data are only used for Boostnote improvements.</p>
<input onChange={(e) => this.handleConfigChange(e)}
checked={this.state.config.amaEnabled}
ref='amaEnabled'
type='checkbox'
/>
Enable to send analytics to our servers<br />
<button styleName='policy-submit' onClick={(e) => this.handleSaveButtonClick(e)}>Save</button>
</div>
)
}

View File

@@ -4,11 +4,9 @@
padding 15px
white-space pre
line-height 1.4
color $ui-text-color
color alpha($ui-text-color, 90%)
width 100%
.clear
clear both
font-size 14px
.top
text-align left
@@ -34,26 +32,23 @@
.description
font-size 14px
.madeBy
font-size 14px
$ui-inactive-text-color
.copyright
font-size 14px
$ui-inactive-text-color
.list
list-style square
padding-left 2em
li
white-space normal
padding-bottom 10px
a
color #4E8EC6
text-decoration none
.policy
font-size 20px
margin-bottom 10px
.policy-submit
margin-top 10px
body[data-theme="dark"]
.root
color $tab--dark-text-color
.madeBy
color $ui-dark-inactive-text-color
.copyright
color $ui-dark-inactive-text-color
color alpha($tab--dark-text-color, 80%)

View File

@@ -20,17 +20,6 @@ top-bar--height = 50px
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
@@ -45,22 +34,20 @@ top-bar--height = 50px
text-align left
width 100px
margin 4px 0
padding 7px 0
padding-left 7px
padding 5px 0
padding-left 10px
border none
border-radius 3px
border-radius 2px
background-color transparent
color $ui-text-color
font-size 14px
&:hover
color $ui-active-color
.nav-button--active
@extend .nav-button
color white
background-color $ui-active-color
color $ui-text-color
background-color $ui-button--active-backgroundColor
&:hover
color white
color $ui-text-color
.nav-button-icon
display block
@@ -91,3 +78,10 @@ body[data-theme="dark"]
color $tab--dark-text-color
&:hover
color $ui-dark-text-color
.nav-button--active
@extend .nav-button
color white
background-color $dark-primary-button-background--active
&:hover
color white

View File

@@ -35,7 +35,7 @@
border $ui-border
border-radius 2px
padding 0 5px
outline none
.header-control
float right
@@ -71,7 +71,7 @@
background-color darken(white, 3%)
.folderList-item-left
height 30px
border-left solid 4px transparent
border-left solid 2px transparent
padding 0 10px
line-height 30px
float left
@@ -105,6 +105,7 @@
border $ui-border
border-radius 2px
padding 0 5px
outline none
.folderList-item-right
float right

View File

@@ -28,12 +28,15 @@
.list-control
height 30px
.list-control-addStorageButton
position absolute
top 7px
right 20px
height $tab--button-height
padding 0 15px
border $ui-border
colorDefaultButton()
font-size $tab--button-font-size
border-radius $tab--button-border-radius
border-radius 2px
.addStorage
margin-bottom 15px

View File

@@ -4,44 +4,66 @@ import styles from './ConfigTab.styl'
import ConfigManager from 'browser/main/lib/ConfigManager'
import store from 'browser/main/store'
import consts from 'browser/lib/consts'
import ReactCodeMirror from 'react-codemirror'
import CodeMirror from 'codemirror'
const OSX = global.process.platform === 'darwin'
class UiTab extends React.Component {
constructor (props) {
super(props)
this.state = {
config: props.config
config: props.config,
codemirrorTheme: props.config.editor.theme
}
}
componentWillMount () {
CodeMirror.autoLoadMode(ReactCodeMirror, 'javascript')
}
handleUIChange (e) {
let { config } = this.state
const { codemirrorTheme } = this.state
let checkHighLight = document.getElementById('checkHighLight')
config.ui = {
theme: this.refs.uiTheme.value,
disableDirectWrite: this.refs.uiD2w != null
? this.refs.uiD2w.checked
: false
}
config.editor = {
theme: this.refs.editorTheme.value,
fontSize: this.refs.editorFontSize.value,
fontFamily: this.refs.editorFontFamily.value,
indentType: this.refs.editorIndentType.value,
indentSize: this.refs.editorIndentSize.value,
switchPreview: this.refs.editorSwitchPreview.value,
keyMap: this.refs.editorKeyMap.value
}
config.preview = {
fontSize: this.refs.previewFontSize.value,
fontFamily: this.refs.previewFontFamily.value,
codeBlockTheme: this.refs.previewCodeBlockTheme.value,
lineNumber: this.refs.previewLineNumber.checked
if (checkHighLight === null) {
checkHighLight = document.createElement('link')
checkHighLight.setAttribute('id', 'checkHighLight')
checkHighLight.setAttribute('rel', 'stylesheet')
document.head.appendChild(checkHighLight)
}
this.setState({ config })
const newConfig = {
ui: {
theme: this.refs.uiTheme.value,
disableDirectWrite: this.refs.uiD2w != null
? this.refs.uiD2w.checked
: false
},
editor: {
theme: this.refs.editorTheme.value,
fontSize: this.refs.editorFontSize.value,
fontFamily: this.refs.editorFontFamily.value,
indentType: this.refs.editorIndentType.value,
indentSize: this.refs.editorIndentSize.value,
switchPreview: this.refs.editorSwitchPreview.value,
keyMap: this.refs.editorKeyMap.value
},
preview: {
fontSize: this.refs.previewFontSize.value,
fontFamily: this.refs.previewFontFamily.value,
codeBlockTheme: this.refs.previewCodeBlockTheme.value,
lineNumber: this.refs.previewLineNumber.checked
}
}
const newCodemirrorTheme = this.refs.editorTheme.value
if (newCodemirrorTheme !== codemirrorTheme) {
checkHighLight.setAttribute('href', `../node_modules/codemirror/theme/${newCodemirrorTheme}.css`)
}
this.setState({ config: newConfig, codemirrorTheme: newCodemirrorTheme })
}
handleSaveUIClick (e) {
@@ -61,8 +83,8 @@ class UiTab extends React.Component {
render () {
const themes = consts.THEMES
const { config } = this.state
const { config, codemirrorTheme } = this.state
const codemirrorSampleCode = 'function iamHappy (happy) {\n\tif (happy) {\n\t console.log("I am Happy!")\n\t} else {\n\t console.log("I am not Happy!")\n\t}\n};'
return (
<div styleName='root'>
<div styleName='group'>
@@ -113,6 +135,9 @@ class UiTab extends React.Component {
})
}
</select>
<div styleName='code-mirror'>
<ReactCodeMirror value={codemirrorSampleCode} options={{ lineNumbers: true, readOnly: true, mode: 'javascript', theme: codemirrorTheme }} />
</div>
</div>
</div>
<div styleName='group-section'>
@@ -191,6 +216,7 @@ class UiTab extends React.Component {
>
<option value='sublime'>default</option>
<option value='vim'>vim</option>
<option value='emacs'>emacs</option>
</select>
<span styleName='note-for-keymap'>Please reload boostnote after you change the keymap</span>
</div>
@@ -253,7 +279,7 @@ class UiTab extends React.Component {
<button styleName='group-control-rightButton'
onClick={(e) => this.handleSaveUIClick(e)}
>
Save UI Config
Save
</button>
</div>
</div>

View File

@@ -5,6 +5,7 @@ import HotkeyTab from './HotkeyTab'
import UiTab from './UiTab'
import InfoTab from './InfoTab'
import StoragesTab from './StoragesTab'
import ModalEscButton from 'browser/components/ModalEscButton'
import CSSModules from 'browser/lib/CSSModules'
import styles from './PreferencesModal.styl'
@@ -43,7 +44,12 @@ class Preferences extends React.Component {
switch (this.state.currentTab) {
case 'INFO':
return <InfoTab />
return (
<InfoTab
dispatch={dispatch}
config={config}
/>
)
case 'HOTKEY':
return (
<HotkeyTab
@@ -115,12 +121,9 @@ class Preferences extends React.Component {
onKeyDown={(e) => this.handleKeyDown(e)}
>
<div styleName='top-bar'>
<p>Your menu for Boostnote</p>
<p>Your preferences 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>
<ModalEscButton handleEscButtonClick={(e) => this.handleEscButtonClick(e)} />
<div styleName='nav'>
{navButtons}
</div>

View File

@@ -3,6 +3,7 @@ import CSSModules from 'browser/lib/CSSModules'
import styles from './RenameFolderModal.styl'
import dataApi from 'browser/main/lib/dataApi'
import store from 'browser/main/store'
import ModalEscButton from 'browser/components/ModalEscButton'
class RenameFolderModal extends React.Component {
constructor (props) {
@@ -72,9 +73,7 @@ class RenameFolderModal extends React.Component {
<div styleName='header'>
<div styleName='title'>Rename Folder</div>
</div>
<button styleName='closeButton'
onClick={(e) => this.handleCloseButtonClick(e)}
>Close</button>
<ModalEscButton handleEscButtonClick={(e) => this.handleCloseButtonClick(e)} />
<div styleName='control'>
<input styleName='control-input'

View File

@@ -6,24 +6,13 @@
.header
height 50px
font-size 18px
font-size 16px
line-height 50px
padding 0 15px
background-color $ui-backgroundColor
border-bottom solid 1px $ui-borderColor
color $ui-text-color
.closeButton
position absolute
top 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
@@ -40,7 +29,7 @@
background-color transparent
outline none
vertical-align middle
font-size 18px
font-size 14px
text-align center
&:disabled
background-color $ui-input--disabled-backgroundColor
@@ -65,13 +54,12 @@ body[data-theme="dark"]
border-color $ui-dark-borderColor
color $ui-dark-text-color
.closeButton
border-color $ui-dark-borderColor
color $ui-dark-text-color
colorDarkDefaultButton()
.description
.description
color $ui-inactive-text-color
.control-input
border-color $ui-dark-borderColor
color $ui-dark-text-color
.control-confirmButton
colorDarkPrimaryButton()

View File

@@ -11,7 +11,8 @@ function defaultDataMap () {
starredSet: new Set(),
storageNoteMap: new Map(),
folderNoteMap: new Map(),
tagNoteMap: new Map()
tagNoteMap: new Map(),
trashedSet: new Set()
}
}
@@ -24,7 +25,8 @@ function data (state = defaultDataMap(), action) {
state.storageMap.set(storage.key, storage)
})
action.notes.forEach((note) => {
action.notes.some((note) => {
if (note === undefined) return true
let uniqueKey = note.storage + '-' + note.key
let folderKey = note.storage + '-' + note.folder
state.noteMap.set(uniqueKey, note)
@@ -33,6 +35,10 @@ function data (state = defaultDataMap(), action) {
state.starredSet.add(uniqueKey)
}
if (note.isTrashed) {
state.trashedSet.add(uniqueKey)
}
let storageNoteList = state.storageNoteMap.get(note.storage)
if (storageNoteList == null) {
storageNoteList = new Set(storageNoteList)
@@ -77,6 +83,15 @@ function data (state = defaultDataMap(), action) {
}
}
if (oldNote == null || oldNote.isTrashed !== note.isTrashed) {
state.trashedSet = new Set(state.trashedSet)
if (note.isTrashed) {
state.trashedSet.add(uniqueKey)
} else {
state.trashedSet.delete(uniqueKey)
}
}
// Update storageNoteMap if oldNote doesn't exist
if (oldNote == null) {
state.storageNoteMap = new Map(state.storageNoteMap)
@@ -162,6 +177,11 @@ function data (state = defaultDataMap(), action) {
state.starredSet.delete(originKey)
}
if (originNote.isTrashed) {
state.trashedSet = new Set(state.trashedSet)
state.trashedSet.delete(originKey)
}
// From storageNoteMap
state.storageNoteMap = new Map(state.storageNoteMap)
let noteSet = state.storageNoteMap.get(originNote.storage)
@@ -198,6 +218,15 @@ function data (state = defaultDataMap(), action) {
}
}
if (oldNote == null || oldNote.isTrashed !== note.isTrashed) {
state.trashedSet = new Set(state.trashedSet)
if (note.isTrashed) {
state.trashedSet.add(uniqueKey)
} else {
state.trashedSet.delete(uniqueKey)
}
}
// Update storageNoteMap if oldNote doesn't exist
if (oldNote == null) {
state.storageNoteMap = new Map(state.storageNoteMap)
@@ -282,6 +311,11 @@ function data (state = defaultDataMap(), action) {
state.starredSet.delete(uniqueKey)
}
if (targetNote.isTrashed) {
state.trashedSet = new Set(state.trashedSet)
state.trashedSet.delete(uniqueKey)
}
// From folderNoteMap
let folderKey = targetNote.storage + '-' + targetNote.folder
state.folderNoteMap = new Map(state.folderNoteMap)
@@ -347,6 +381,11 @@ function data (state = defaultDataMap(), action) {
state.starredSet.delete(noteKey)
}
if (note.isTrashed) {
state.trashedSet = new Set(state.trashedSet)
state.trashedSet.delete(noteKey)
}
// Delete key from tag map
state.tagNoteMap = new Map(state.tagNoteMap)
note.tags.forEach((tag) => {

View File

@@ -11,7 +11,7 @@ $sideNav--folded-width = 44px
$topBar-height = 60px
// UI default
$ui-text-color = #515151
$ui-text-color = #333333
$ui-inactive-text-color = #939395
$ui-borderColor = #D1D1D1
$ui-backgroundColor = #FFFFFF
@@ -23,9 +23,9 @@ $ui-tag-backgroundColor = rgba(0, 0, 0, 0.3)
// UI Button
$ui-button-color = #939395
$ui-button--hover-backgroundColor = rgba(126, 127, 129, 0.08)
$ui-button--hover-backgroundColor = #D9D9D9
$ui-button--active-color = white
$ui-button--active-backgroundColor = #6AA5E9
$ui-button--active-backgroundColor = #D9D9D9
$ui-button--focus-borderColor = lighten(#369DCD, 25%)
// UI Tooltip
@@ -67,29 +67,43 @@ $active-border = solid 1px $active-border-color
// Default button
$default-button-background = white
$default-button-background--hover = #e6e6e6
$default-button-background--active = #d4d4d4
$default-button-background--active = #D9D9D9
colorDefaultButton()
background-color $default-button-background
&:hover
background-color $default-button-background--hover
background-color transparent
&:active
&:active:hover
background-color $default-button-background--active
// Primary button(Brand color)
$primary-button-background = $brand-color
$primary-button-background = alpha($brand-color, 60%)
$primary-button-background--hover = darken($brand-color, 5%)
$primary-button-background--active = darken($brand-color, 10%)
colorPrimaryButton()
color white
background-color $primary-button-background
color $ui-text-color
background-color $default-button-background--hover
&:hover
background-color $primary-button-background--hover
background-color $default-button-background--active
&:active
&:active:hover
background-color $primary-button-background--active
background-color $default-button-background--active
// Dark Primary button(Brand color)
$dark-primary-button-background = alpha(#3A404C, 80%)
$dark-primary-button-background--hover = #3A404C
$dark-primary-button-background--active = #3A404C
colorDarkPrimaryButton()
color white
background-color $dark-primary-button-background
&:hover
background-color $dark-primary-button-background--hover
&:active
&:active:hover
background-color $dark-primary-button-background--active
// Danger button(Brand color)
$danger-button-background = #c9302c
@@ -113,13 +127,15 @@ navButtonColor()
border none
color $ui-button-color
background-color transparent
transition color background-color 0.15s
transition 0.15s
&:hover
background-color $ui-button--hover-backgroundColor
background-color alpha($ui-button--active-backgroundColor, 20%)
transition 0.15s
color $ui-text-color
&:active, &:active:hover
background-color $ui-button--active-backgroundColor
color $ui-button--active-color
color $ui-text-color
transition 0.15s
/**
* # Modal Stuff
* These will be moved lib/modal
@@ -137,20 +153,39 @@ modal()
background-color $modal-background
overflow hidden
border-radius $modal-border-radius
box-shadow 2px 2px 10px gray
box-shadow 0 0 1px rgba(76,86,103,.15), 0 2px 18px rgba(31,37,50,.22)
topBarButtonLight()
width 34px
height 34px
border-radius 17px
font-size 14px
margin 15px 7px
border none
color $ui-button-color
fill $ui-button-color
background-color transparent
&:active
border-color $ui-button--active-backgroundColor
&:hover
background-color alpha($ui-button--hover-backgroundColor, 60%)
.control-lockButton-tooltip
opacity 1
// Dark theme
$ui-dark-active-color = #3A404C
$ui-dark-borderColor = lighten(#21252B, 20%)
$ui-dark-backgroundColor = #1D1D1D
$ui-dark-noteList-backgroundColor = #181818
$ui-dark-noteDetail-backgroundColor = #0D0D0D
$ui-dark-tag-backgroundColor = rgba(255, 255, 255, 0.3)
$ui-dark-backgroundColor = #1E2124
$ui-dark-noteList-backgroundColor = #282C30
$ui-dark-noteDetail-backgroundColor = #2D3033
$ui-dark-tag-backgroundColor = #3A404C
$dark-background-color = lighten($ui-dark-backgroundColor, 10%)
$ui-dark-text-color = #DDDDDD
$ui-dark-button--active-color = white
$ui-dark-button--active-backgroundColor = #6AA5E9
$ui-dark-button--active-color = #f4f4f4
$ui-dark-button--active-backgroundColor = #3A404C
$ui-dark-button--hover-backgroundColor = lighten($ui-dark-backgroundColor, 10%)
$ui-dark-button--focus-borderColor = lighten(#369DCD, 25%)
$ui-dark-topbar-button-color = #939395
$dark-default-button-background = $ui-dark-backgroundColor
$dark-default-button-background--hover = $ui-dark-button--hover-backgroundColor
@@ -181,14 +216,29 @@ navDarkButtonColor()
border none
color $ui-dark-button-color
background-color transparent
transition color background-color 0.15s
transition 0.15s
&:hover
color white
color $ui-dark-text-color
background-color $ui-dark-button--hover-backgroundColor
transition 0.15s
&:active
&:active:hover
transition 0.15s
color $ui-dark-text-color
topBarButtonDark()
border-color $ui-dark-borderColor
color $ui-dark-topbar-button-color
&:hover
background-color $dark-default-button-background--hover
color $ui-dark-tooltip-text-color
&:active
border-color $ui-dark-button--focus-borderColor
&:active:hover
background-color $ui-dark-button--active-backgroundColor
color $ui-dark-button--active-color
color $ui-dark-tooltip-text-color
&:focus
border-color $ui-button--focus-borderColor
$ui-dark-tooltip-text-color = white
$ui-dark-tooltip-backgroundColor = alpha(#444, 70%)

View File

@@ -1,23 +1,71 @@
# Contributing to Boostnote
# Contributing to Boostnote (English)
> English below.
### When you open an issue of a bug report
There are no issue template. But there is a request.
## Pull requestの著作権について
**Please paste screenshots of Boostnote with developer tool open**
Pull requestをすることはその変化分のコードの著作権をMAISIN&CO.に譲渡することに同意することになります。
Thank you for your help in advance.
アプリケーションのLicenseのをいつでも変える選択肢を残したいからです。
しかし、これはいずれかBoostnoteが有料の商用アプリになる可能性がある話ではありません。
もし、このアプリケーションで金を稼ごうとするならBoostnote専用のCloud storageの提供やMobile appとの連動、何か特殊なプレミアム機能の提供など形になると思います。
現在考えられているのは、GPL v3の場合、他のライセンスとの互換が不可能であるため、もしより自由なLicense(BSD, MIT)に変える時に改めて著作権者としてライセンスし直す選択肢を残したいぐらいのイメージです。
### About copyright of Pull Request
---
# Contributing to Boostnote(ENG)
## About copyright of Pull Request
If you make a pull request, It means you agree to transfer the copyright of the code changes to MAISIN&CO.
If you make a pull request, It means you agree to transfer the copyright of the code changes to Maisin&Co.
It doesn't mean Boostnote will become a paid app. If we want to earn some money, We will try other way, which is some kind of cloud storage, Mobile app integration or some SPECIAL features.
Because GPL v3 is too strict to be compatible with any other License, We thought this is needed to replace the license with much freer one(like BSD, MIT) somewhen.
---
# Contributing to Boostnote (Russian)
### Когда у вас появляется сообщение об ошибке
У нас нет шаблона, по которому вы должны описать ошибку. Просто расскажите, как вы получили ее
**Вставьте скриншот Boostnote с открытым инструментом разработчика (dev tools)**
Благодарим Вас за помощь!
### Об авторских правах Pull Request
Если вы делаете pull request, значит вы согласны передать авторские права на изменения кода в Maisin&Co.
Это не означает, что Boostnote станет платным приложением. Если мы захотим заработать немного денег, мы найдем другой способ. Например, использование облачного хранилища, интеграцией мобильных приложений или другими специальными функциями.
Так как лицензия GPL v3 слишком строгая, чтобы быть совместимой с любой другой лицензией, мы думаем, что нужно заменить лицензию на более свободную (например, BSD, MIT).
---
# Contributing to Boostnote (Korean)
### 버그 리포트를 보고할 때
이슈의 양식은 없습니다. 하지만 부탁이 있습니다.
**개발자 도구를 연 상태의 Boostnote 스크린샷을 첨부해주세요**
도움을 주셔서 감사합니다.
### Pull Request의 저작권에 관하여
당신이 pull request를 요청하면, 코드 변경에 대한 저작권을 Maisin&Co에 양도한다는 것에 동의한다는 의미입니다.
이것은 Boostnote가 유료화가 되는 것을 의미하는 건 아닙니다. 만약 우리가 자금이 필요하다면, 우리는 클라우드 연동, 모바일 앱 통합 혹은 특수한 기능 같은 것을 사용해 수입 창출을 시도할 것입니다.
GPL v3 라이센스는 다른 라이센스와 혼합해 사용하기엔 너무 엄격하므로, 우리는 BSD, MIT 라이센스와 같은 더 자유로운 라이센스로 교체하는 것을 생각하고 있습니다.
---
# Contributing to Boostnote (Japanese)
### バグレポートに関してのissueを立てる時
イシューテンプレートはありませんが、1つお願いがあります。
**開発者ツールを開いた状態のBoostnoteのスクリーンショットを貼ってください**
よろしくお願いします。
### Pull requestの著作権について
Pull requestをすることはその変化分のコードの著作権をMaisin&Co.に譲渡することに同意することになります。
アプリケーションのLicenseをいつでも変える選択肢を残したいと思うからです。
これはいずれかBoostnoteが有料の商用アプリになる可能性がある話ではありません。
もし、このアプリケーションに料金が発生する時は、Boostnote専用のCloud storageの提供やMobile appとの連動、何か特殊なプレミアム機能の提供など形になります。
現在考えられているのは、GPL v3の場合、他のライセンスとの互換が不可能であるため、もしより自由なLicense(BSD, MIT)に変える時に改めて著作権者としてライセンスし直す選択肢を残すイメージです。

View File

@@ -1,52 +1,52 @@
# Build
## Environments
* npm: 4.x
* node: 7.x
You should use `npm v4.x` because `$ grand pre-build` fails on `v5.x`.
## Development
We use Webpack HMR to develop Boostnote.
You can use following commands to use default configuration at the top of project directory.
Running the following commands, at the top of the project directory, will start Boostnote with the default configurations.
Install requirement packages.
Install the required packages using yarn.
```
$ npm install
$ yarn
```
Build codes.
Build and run.
```
$ npm run webpack
$ yarn run dev-start
```
After a few seconds, you will see this message.
This command runs `yarn run webpack` and `yarn run hot` in parallel. It is the same as running these commands in two terminals.
```
webpack: bundle is now VALID.
```
The `webpack` will watch for code changes and then apply them automatically.
Then, we have to run the app.
```
$ npm run hot
```
> Actually the app can be start with `npm start`. However, the app will use the compiled script.
If the following error occurs: `Failed to load resource: net::ERR_CONNECTION_REFUSED`, please reload Boostnote.
By this, webpack will watch the code changes and apply it automatically.
![net::ERR_CONNECTION_REFUSED](https://cloud.githubusercontent.com/assets/11307908/24343004/081e66ae-1279-11e7-8d9e-7f478043d835.png)
> ### Notice
> There are some cases you have to refresh app yourself.
> 1. When editing constructor method of a component
> 2. When adding a new css class(same to 1: CSS class is re-written by each component. This process occurs at Constructor method.)
> There are some cases where you have to refresh the app manually.
> 1. When editing a constructor method of a component
> 2. When adding a new css class (similar to 1: the CSS class is re-written by each component. This process occurs at the Constructor method.)
## Deploy
We use Grunt.
Acutal deploy can be run by `grunt`. However, you shouldn't use because the default task is including codesign and authenticode.
We use Grunt to automate deployment.
You can build the program by using `grunt`. However, we don't recommend this because the default task includes codesign and authenticode.
So, we prepare a script which just make an executable file.
So, we've prepared a separate script which just makes an executable file.
```
grunt pre-build
```
You will find the executable from `dist`. In this case, auto updater won't work because the app isn't signed.
You will find the executable in the `dist` directory. Note, the auto updater won't work because the app isn't signed.
If you are necessary, you can do codesign or authenticode by this excutable.
If you find it necessary, you can use codesign or authenticode with this executable.

20
docs/debug.md Normal file
View File

@@ -0,0 +1,20 @@
# How to debug Boostnote (Electron app)
Boostnote is an Electron app so it's based on Chromium; developers can use `Developer Tools` just like Google Chrome.
You can toggle the `Developer Tools` like this:
![how_to_toggle_devTools](https://cloud.githubusercontent.com/assets/11307908/24343585/162187e2-127c-11e7-9c01-23578db03ecf.png)
The `Developer Tools` will look like this:
![Developer_Tools](https://cloud.githubusercontent.com/assets/11307908/24343545/eff9f3a6-127b-11e7-94cf-cb67bfda634a.png)
When errors occur, the error messages are displayed at the `console`.
## Debugging
For example, you can use the `debugger` to set a breakpoint in the code like this:
![debugger](https://cloud.githubusercontent.com/assets/11307908/24343879/9459efea-127d-11e7-9943-f60bf7f66d4a.png)
This is just an illustrative example, you should find a way to debug which fits your style.
## References
* [Official document of Google Chrome about debugging](https://developer.chrome.com/devtools)

View File

@@ -5,25 +5,25 @@
Webpack HRMを使います。
次の命令から私達がしておいた設定を使うことができます。
```
npm run webpack
```
数秒後、次のメッセージが表示されます。
依存するパッケージをインストールします。
```
webpack: bundle is now VALID.
$ yarn
```
では、アプリを起動します。
ビルドして実行します。
```
npm run hot
$ yarn run dev-start
```
> 元々、アプリは`npm start`から起動できます。しかし、この場合、コンパイルされたスクリプトを利用します。
このコマンドは `yarn run webpack``yarn run hot`を並列に実行します。つまりこのコマンドは2つのターミナルで同時にこれらのコマンドを実行するのと同じことです。
これにより、Webpackが自動的にコードの変更を確認し、それを適用してくれるようになります。
そして、Webpackが自動的にコードの変更を確認し、それを適用してくれるようになります。
もし、 `Failed to load resource: net::ERR_CONNECTION_REFUSED`というエラーが起きた場合、Boostnoteをリロードしてください。
![net::ERR_CONNECTION_REFUSED](https://cloud.githubusercontent.com/assets/11307908/24343004/081e66ae-1279-11e7-8d9e-7f478043d835.png)
> ### 注意
> 時々、直接リフレッシュをする必要があります。

20
docs/jp/debug.md Normal file
View File

@@ -0,0 +1,20 @@
# Boostnote(electronアプリケーション)のデバッグ方法について
Boostnoteを作っているelectronはChromiumからできており、開発者は `Developer Tools`をGoogle Chromeと同じように使うことができます。
Developer Toolsの切り替え方法はこちらです:
![how_to_toggle_devTools](https://cloud.githubusercontent.com/assets/11307908/24343585/162187e2-127c-11e7-9c01-23578db03ecf.png)
実際のデベロッパーツールはこちらです:
![Developer_Tools](https://cloud.githubusercontent.com/assets/11307908/24343545/eff9f3a6-127b-11e7-94cf-cb67bfda634a.png)
何かエラーが起きた場合 `console`にエラーメッセージが表示されます。
## デバッグ
例えば、 `debugger`をコード中にブレークポイントとして挟む方法があります。
![debugger](https://cloud.githubusercontent.com/assets/11307908/24343879/9459efea-127d-11e7-9943-f60bf7f66d4a.png)
ですがこれは一例にしか過ぎません。最もあなたに合うデバッグ方法を見つけた方がいいでしょう。
## 参考
* [デバッグに関するGoogle Chromeの公式ドキュメント](https://developer.chrome.com/devtools)

View File

@@ -6,7 +6,7 @@ Webpack HRM을 개발을 위해 사용합니다.
다음 명령을 통해 저희가 해둔 설정을 사용 할 수 있습니다.
```
npm run webpack
yarn run webpack
```
몇 초 후, 다음 메세지를 보게 될겁니다.
@@ -18,10 +18,10 @@ webpack: bundle is now VALID.
그럼 앱을 실행합시다.
```
npm run hot
yarn run hot
```
> 원래 앱은 `npm start`로 실행가능합니다. 하지만 이 경우, 컴파일된 스크립트를 사용할 것입니다.
> 원래 앱은 `yarn start`로 실행가능합니다. 하지만 이 경우, 컴파일된 스크립트를 사용할 것입니다.
이로써 웹팩이 자동적으로 코드변경을 확인하고 적용해줄 것입니다.

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