diff --git a/.gitignore b/.gitignore index 972eac28..b4116c1f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ +.DS_Store .env +Desktop.ini +Thumbs.db node_modules/* !node_modules/boost /dist diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index b1b463c7..8ecf1851 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -96,7 +96,8 @@ export default class CodeEditor extends React.Component { fontSize: config['editor-font-size'], fontFamily: config['editor-font-family'], indentType: config['editor-indent-type'], - indentSize: config['editor-indent-size'] + indentSize: config['editor-indent-size'], + themeSyntax: config['theme-syntax'] } this.silentChange = false @@ -114,7 +115,7 @@ export default class CodeEditor extends React.Component { var editor = this.editor = ace.edit(el) editor.$blockScrolling = Infinity editor.renderer.setShowGutter(true) - editor.setTheme('ace/theme/xcode') + editor.setTheme('ace/theme/' + this.state.themeSyntax) editor.moveCursorTo(0, 0) editor.setReadOnly(!!this.props.readOnly) editor.setFontSize(this.state.fontSize) @@ -202,9 +203,13 @@ export default class CodeEditor extends React.Component { fontSize: config['editor-font-size'], fontFamily: config['editor-font-family'], indentType: config['editor-indent-type'], - indentSize: config['editor-indent-size'] + indentSize: config['editor-indent-size'], + themeSyntax: config['theme-syntax'] }, function () { - var session = this.editor.getSession() + var editor = this.editor + editor.setTheme('ace/theme/' + this.state.themeSyntax) + + var session = editor.getSession() session.setUseSoftTabs(this.state.indentType === 'space') session.setTabSize(!isNaN(this.state.indentSize) ? parseInt(this.state.indentSize, 10) : 4) }) diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js index b9133679..5d10cca8 100644 --- a/browser/components/MarkdownPreview.js +++ b/browser/components/MarkdownPreview.js @@ -20,6 +20,7 @@ const sanitizeOpts = { allowedClasses: { 'a': ['lineAnchor'], 'div': ['math'], + 'pre': ['hljs'], 'span': ['math', 'hljs-*'], 'code': ['language-*'] }, diff --git a/browser/finder/index.js b/browser/finder/index.js index ef42feff..9ecb2753 100644 --- a/browser/finder/index.js +++ b/browser/finder/index.js @@ -9,11 +9,27 @@ import FinderDetail from './FinderDetail' import actions, { selectArticle, searchArticle } from './actions' import _ from 'lodash' import dataStore from 'browser/lib/dataStore' - +import fetchConfig from '../lib/fetchConfig' const electron = require('electron') const { clipboard, ipcRenderer, remote } = electron const path = require('path') +let config = fetchConfig() +applyConfig(config) + +ipcRenderer.on('config-apply', function (e, newConfig) { + config = newConfig + applyConfig(config) +}) + +function applyConfig () { + let body = document.body + body.setAttribute('data-theme', config['theme-ui']) + + let hljsCss = document.getElementById('hljs-css') + hljsCss.setAttribute('href', '../node_modules/highlight.js/styles/' + config['theme-code'] + '.css') +} + if (process.env.NODE_ENV !== 'production') { window.addEventListener('keydown', function (e) { if (e.keyCode === 73 && e.metaKey && e.altKey) { diff --git a/browser/lib/fetchConfig.js b/browser/lib/fetchConfig.js index bd57d4ca..e1d40dd4 100644 --- a/browser/lib/fetchConfig.js +++ b/browser/lib/fetchConfig.js @@ -13,7 +13,10 @@ const defaultConfig = { 'preview-font-size': '14', 'preview-font-family': 'Lato', 'switch-preview': 'blur', - 'disable-direct-write': false + 'disable-direct-write': false, + 'theme-ui': 'light', + 'theme-code': 'xcode', + 'theme-syntax': 'xcode' } export default function fetchConfig () { diff --git a/browser/lib/hljsThemes.js b/browser/lib/hljsThemes.js new file mode 100644 index 00000000..3a288c47 --- /dev/null +++ b/browser/lib/hljsThemes.js @@ -0,0 +1,78 @@ +const hljsThemeList = [ + {caption: 'Default', name: 'default'}, + {caption: 'Agate', name: 'agate'}, + {caption: 'Androidstudio', name: 'androidstudio'}, + {caption: 'Arduino Light', name: 'arduino-light'}, + {caption: 'Arta', name: 'arta'}, + {caption: 'Ascetic', name: 'ascetic'}, + {caption: 'Atelier Cave Dark', name: 'atelier-cave-dark'}, + {caption: 'Atelier Cave Light', name: 'atelier-cave-light'}, + {caption: 'Atelier Dune Dark', name: 'atelier-dune-dark'}, + {caption: 'Atelier Dune Light', name: 'atelier-dune-light'}, + {caption: 'Atelier Estuary Dark', name: 'atelier-estuary-dark'}, + {caption: 'Atelier Estuary Light', name: 'atelier-estuary-light'}, + {caption: 'Atelier Forest Dark', name: 'atelier-forest-dark'}, + {caption: 'Atelier Forest Light', name: 'atelier-forest-light'}, + {caption: 'Atelier Heath Dark', name: 'atelier-heath-dark'}, + {caption: 'Atelier Heath Light', name: 'atelier-heath-light'}, + {caption: 'Atelier Lakeside Dark', name: 'atelier-lakeside-dark'}, + {caption: 'Atelier Lakeside Light', name: 'atelier-lakeside-light'}, + {caption: 'Atelier Plateau Dark', name: 'atelier-plateau-dark'}, + {caption: 'Atelier Plateau Light', name: 'atelier-plateau-light'}, + {caption: 'Atelier Savanna Dark', name: 'atelier-savanna-dark'}, + {caption: 'Atelier Savanna Light', name: 'atelier-savanna-light'}, + {caption: 'Atelier Seaside Dark', name: 'atelier-seaside-dark'}, + {caption: 'Atelier Seaside Light', name: 'atelier-seaside-light'}, + {caption: 'Atelier Sulphurpool Dark', name: 'atelier-sulphurpool-dark'}, + {caption: 'Atelier Sulphurpool Light', name: 'atelier-sulphurpool-light'}, + {caption: 'Brown Paper', name: 'brown-paper'}, + {caption: 'Codepen Embed', name: 'codepen-embed'}, + {caption: 'Color Brewer', name: 'color-brewer'}, + {caption: 'Dark', name: 'dark'}, + {caption: 'Darkula', name: 'darkula'}, + {caption: 'Docco', name: 'docco'}, + {caption: 'Dracula', name: 'dracula'}, + {caption: 'Far', name: 'far'}, + {caption: 'Foundation', name: 'foundation'}, + {caption: 'Github Gist', name: 'github-gist'}, + {caption: 'Github', name: 'github'}, + {caption: 'Googlecode', name: 'googlecode'}, + {caption: 'Grayscale', name: 'grayscale'}, + {caption: 'Gruvbox Dark', name: 'gruvbox.dark'}, + {caption: 'Gruvbox Light', name: 'gruvbox.light'}, + {caption: 'Hopscotch', name: 'hopscotch'}, + {caption: 'Hybrid', name: 'hybrid'}, + {caption: 'Idea', name: 'idea'}, + {caption: 'Ir Black', name: 'ir-black'}, + {caption: 'Kimbie Dark', name: 'kimbie.dark'}, + {caption: 'Kimbie Light', name: 'kimbie.light'}, + {caption: 'Magula', name: 'magula'}, + {caption: 'Mono Blue', name: 'mono-blue'}, + {caption: 'Monokai Sublime', name: 'monokai-sublime'}, + {caption: 'Monokai', name: 'monokai'}, + {caption: 'Obsidian', name: 'obsidian'}, + {caption: 'Paraiso Dark', name: 'paraiso-dark'}, + {caption: 'Paraiso Light', name: 'paraiso-light'}, + {caption: 'Pojoaque', name: 'pojoaque'}, + {caption: 'Qtcreator Dark', name: 'qtcreator_dark'}, + {caption: 'Qtcreator Light', name: 'qtcreator_light'}, + {caption: 'Railscasts', name: 'railscasts'}, + {caption: 'Rainbow', name: 'rainbow'}, + {caption: 'School Book', name: 'school-book'}, + {caption: 'Solarized Dark', name: 'solarized-dark'}, + {caption: 'Solarized Light', name: 'solarized-light'}, + {caption: 'Sunburst', name: 'sunburst'}, + {caption: 'Tomorrow Night Blue', name: 'tomorrow-night-blue'}, + {caption: 'Tomorrow Night Bright', name: 'tomorrow-night-bright'}, + {caption: 'Tomorrow Night Eighties', name: 'tomorrow-night-eighties'}, + {caption: 'Tomorrow Night', name: 'tomorrow-night'}, + {caption: 'Tomorrow', name: 'tomorrow'}, + {caption: 'Vs', name: 'vs'}, + {caption: 'Xcode', name: 'xcode'}, + {caption: 'Xt 256', name: 'xt256'}, + {caption: 'Zenburn', name: 'zenburn'} +] + +export default function hljsTheme () { + return hljsThemeList +} diff --git a/browser/lib/markdown.js b/browser/lib/markdown.js index d75bdf02..7dad1e39 100644 --- a/browser/lib/markdown.js +++ b/browser/lib/markdown.js @@ -1,6 +1,6 @@ import markdownit from 'markdown-it' import emoji from 'markdown-it-emoji' -import math from 'markdown-it-math' +import math from '@rokt33r/markdown-it-math' import hljs from 'highlight.js' var md = markdownit({ @@ -11,10 +11,14 @@ var md = markdownit({ highlight: function (str, lang) { if (lang && hljs.getLanguage(lang)) { try { - return hljs.highlight(lang, str).value + return '
' +
+        hljs.highlight(lang, str).value +
+        '
' } catch (e) {} } - return str.replace(/\&/g, '&').replace(/\/g, '>').replace(/\"/g, '"') + return '
' +
+    str.replace(/\&/g, '&').replace(/\/g, '>').replace(/\"/g, '"') +
+    '
' } }) md.use(emoji, { diff --git a/browser/main/index.js b/browser/main/index.js index 9e305ad1..0c15732b 100644 --- a/browser/main/index.js +++ b/browser/main/index.js @@ -7,10 +7,37 @@ require('!!style!css!stylus?sourceMap!../styles/main/index.styl') import { openModal } from 'browser/lib/modal' import OSSAnnounceModal from './modal/OSSAnnounceModal' import activityRecord from 'browser/lib/activityRecord' +import fetchConfig from '../lib/fetchConfig' const electron = require('electron') const ipc = electron.ipcRenderer const path = require('path') +const remote = electron.remote + +let config = fetchConfig() +applyConfig(config) + +ipc.on('config-apply', function (e, newConfig) { + config = newConfig + applyConfig(config) +}) + +function applyConfig (config) { + let body = document.body + body.setAttribute('data-theme', config['theme-ui']) + + let hljsCss = document.getElementById('hljs-css') + hljsCss.setAttribute('href', '../node_modules/highlight.js/styles/' + config['theme-code'] + '.css') +} + +if (process.env.NODE_ENV !== 'production') { + window.addEventListener('keydown', function (e) { + if (e.keyCode === 73 && e.metaKey && e.altKey) { + remote.getCurrentWindow().toggleDevTools() + } + }) +} + activityRecord.init() window.addEventListener('online', function () { ipc.send('check-update', 'check-update') diff --git a/browser/main/modal/Preference/AppSettingTab.js b/browser/main/modal/Preference/AppSettingTab.js index 8e284fd2..c44675a8 100644 --- a/browser/main/modal/Preference/AppSettingTab.js +++ b/browser/main/modal/Preference/AppSettingTab.js @@ -2,10 +2,12 @@ import React, { PropTypes } from 'react' import linkState from 'browser/lib/linkState' import { updateUser } from '../../actions' import fetchConfig from 'browser/lib/fetchConfig' +import hljsTheme from 'browser/lib/hljsThemes' const electron = require('electron') const ipc = electron.ipcRenderer const remote = electron.remote +const ace = window.ace const OSX = global.process.platform === 'darwin' @@ -114,11 +116,13 @@ export default class AppSettingTab extends React.Component { {userAlert.message}

) : null + let aceThemeList = ace.require("ace/ext/themelist") + let hljsThemeList = hljsTheme() return (
-
User's info
+
User's info
@@ -129,7 +133,7 @@ export default class AppSettingTab extends React.Component {
-
Text
+
Editor
this.handleConfigKeyDown(e)} type='text'/> @@ -154,6 +158,7 @@ export default class AppSettingTab extends React.Component {
+
Preview
this.handleConfigKeyDown(e)} type='text'/> @@ -178,7 +183,34 @@ export default class AppSettingTab extends React.Component { ) : null } - +
Theme
+
+ + +
+
+ + +
+
+ + +
diff --git a/browser/main/modal/Preference/FolderRow.js b/browser/main/modal/Preference/FolderRow.js index b3cd72ad..f836e9d1 100644 --- a/browser/main/modal/Preference/FolderRow.js +++ b/browser/main/modal/Preference/FolderRow.js @@ -63,7 +63,7 @@ export default class FolderRow extends React.Component { } handleColorButtonClick (index) { - return e => { + return (e) => { this.setState({ color: index, isColorEditing: false @@ -116,7 +116,7 @@ export default class FolderRow extends React.Component { ? 'active' : null return ( - ) @@ -125,7 +125,7 @@ export default class FolderRow extends React.Component { return (
- {this.state.isColorEditing @@ -139,11 +139,11 @@ export default class FolderRow extends React.Component { }
- this.handleNameInputKeyDown(e)} valueLink={this.linkState('name')} type='text'/> + this.handleNameInputKeyDown(e)} valueLink={this.linkState('name')} type='text'/>
- - + +
) @@ -152,8 +152,8 @@ export default class FolderRow extends React.Component {
Are you sure to delete {folder.name} folder?
- - + +
) @@ -162,14 +162,14 @@ export default class FolderRow extends React.Component { return (
- - + +
{folder.name}
- - + +
) diff --git a/browser/main/modal/Preference/FolderSettingTab.js b/browser/main/modal/Preference/FolderSettingTab.js index a466dbe7..2337aa32 100644 --- a/browser/main/modal/Preference/FolderSettingTab.js +++ b/browser/main/modal/Preference/FolderSettingTab.js @@ -75,10 +75,10 @@ export default class FolderSettingTab extends React.Component { {folderElements}
- this.handleNewFolderNameKeyDown(e)} valueLink={this.linkState('name')} type='text' placeholder='New Folder'/> + this.handleNewFolderNameKeyDown(e)} valueLink={this.linkState('name')} type='text' placeholder='New Folder'/>
- +
{alertElement} diff --git a/browser/main/modal/Preferences.js b/browser/main/modal/Preferences.js index 8bea2f3f..01b7ac22 100644 --- a/browser/main/modal/Preferences.js +++ b/browser/main/modal/Preferences.js @@ -8,7 +8,6 @@ import ContactTab from './Preference/ContactTab' import { closeModal } from 'browser/lib/modal' const APP = 'APP' -const HELP = 'HELP' const FOLDER = 'FOLDER' const CONTACT = 'CONTACT' @@ -64,8 +63,6 @@ class Preferences extends React.Component { let { user, folders, dispatch } = this.props switch (this.state.currentTab) { - case HELP: - return () case FOLDER: return ( - - {content} @@ -80,7 +80,7 @@ export default class Tutorial extends React.Component { Boost supports code syntax highlighting.
There are more than 100 different type of language.
- +
) @@ -101,7 +101,7 @@ export default class Tutorial extends React.Component { return (
Are you ready?
- +
) default: diff --git a/browser/main/reducer.js b/browser/main/reducer.js index 9c3db1f7..a41a0749 100644 --- a/browser/main/reducer.js +++ b/browser/main/reducer.js @@ -76,7 +76,7 @@ function folders (state = initialFolders, action) { if (newFolder.name == null || newFolder.name.length === 0) throw new Error('Folder name is required') if (newFolder.name.match(/\//)) throw new Error('`/` is not available for folder name') - let conflictFolder = _.find(state, folder => folder.name.toLowerCase() === newFolder.name.toLowerCase()) + let conflictFolder = _.find(state, (folder) => folder.name.toLowerCase() === newFolder.name.toLowerCase()) if (conflictFolder != null) throw new Error(`${conflictFolder.name} already exists!`) state.push(newFolder) @@ -98,7 +98,7 @@ function folders (state = initialFolders, action) { if (targetFolder == null) throw new Error('Folder doesnt exist') // Name conflict check if (targetFolder.name !== folder.name) { - let conflictFolder = _.find(state, _folder => { + let conflictFolder = _.find(state, (_folder) => { return folder.name.toLowerCase() === _folder.name.toLowerCase() && folder.key !== _folder.key }) if (conflictFolder != null) throw new Error('Name conflicted') @@ -116,7 +116,7 @@ function folders (state = initialFolders, action) { if (state.length < 2) throw new Error('Folder must exist more than one') let targetKey = action.data.key - let targetIndex = _.findIndex(state, folder => folder.key === targetKey) + let targetIndex = _.findIndex(state, (folder) => folder.key === targetKey) if (targetIndex >= 0) { state.splice(targetIndex, 1) } @@ -161,9 +161,9 @@ function articles (state = initialArticles, action) { { let modified = action.data.article let targetKey = action.data.key - let originalIndex = _.findIndex(state.data, _article => targetKey === _article.key) + let originalIndex = _.findIndex(state.data, (_article) => targetKey === _article.key) if (originalIndex === -1) return state - let modifiedIndex = _.findIndex(state.modified, _article => targetKey === _article.key) + let modifiedIndex = _.findIndex(state.modified, (_article) => targetKey === _article.key) modified = compareArticle(state.data[originalIndex], modified) if (modified == null) { diff --git a/browser/styles/finder/index.styl b/browser/styles/finder/index.styl index cd48aa69..a0cb28b4 100644 --- a/browser/styles/finder/index.styl +++ b/browser/styles/finder/index.styl @@ -3,6 +3,7 @@ @import '../mixins/*' global-reset() @import '../shared/*' +@import '../theme/*' iptBgColor = #E6E6E6 iptFocusBorderColor = #369DCD diff --git a/browser/styles/main/ArticleDetail.styl b/browser/styles/main/ArticleDetail.styl index 53180659..9c897eb0 100644 --- a/browser/styles/main/ArticleDetail.styl +++ b/browser/styles/main/ArticleDetail.styl @@ -25,7 +25,6 @@ infoButton() padding 10px background-color #E6E6E6 border-top 1px solid borderColor - border-left 1px solid borderColor &.empty .ArticleDetail-empty-box line-height 72px diff --git a/browser/styles/main/ArticleList.styl b/browser/styles/main/ArticleList.styl index 3efee6f1..4e3a63f5 100644 --- a/browser/styles/main/ArticleList.styl +++ b/browser/styles/main/ArticleList.styl @@ -30,6 +30,8 @@ articleItemColor = #777 height 20px color articleItemColor font-size 11px + i + margin-right 4px .folderName overflow ellipsis display inline-block diff --git a/browser/styles/main/ArticleNavigator.styl b/browser/styles/main/ArticleNavigator.styl index 8c541ed1..90835f51 100644 --- a/browser/styles/main/ArticleNavigator.styl +++ b/browser/styles/main/ArticleNavigator.styl @@ -11,6 +11,7 @@ articleCount = #999 .userInfo height 60px display block + box-sizing content-box border-bottom 1px solid borderColor .userProfileName color brandColor diff --git a/browser/styles/main/index.styl b/browser/styles/main/index.styl index 25d81076..0c24750b 100644 --- a/browser/styles/main/index.styl +++ b/browser/styles/main/index.styl @@ -7,6 +7,7 @@ global-reset() @import './ArticleList' @import './ArticleDetail' @import './modal/*' +@import '../theme/*' DEFAULT_FONTS = 'Lato', helvetica, arial, sans-serif diff --git a/browser/styles/main/modal/CreateNewFolder.styl b/browser/styles/main/modal/CreateNewFolder.styl index af3ec002..1d7870d2 100644 --- a/browser/styles/main/modal/CreateNewFolder.styl +++ b/browser/styles/main/modal/CreateNewFolder.styl @@ -72,7 +72,7 @@ iptFocusBorderColor = #369DCD .confirmBtn display block position absolute - left 180px + left 205px bottom 44px width 240px font-size 24px diff --git a/browser/styles/main/modal/Preferences.styl b/browser/styles/main/modal/Preferences.styl index 9688fe0b..0bb32d97 100644 --- a/browser/styles/main/modal/Preferences.styl +++ b/browser/styles/main/modal/Preferences.styl @@ -8,7 +8,7 @@ iptFocusBorderColor = #369DCD border-radius 5px overflow hidden width 720px - height 450px + height 600px &>.header absolute top left right height 50px diff --git a/browser/styles/mixins/marked.styl b/browser/styles/mixins/marked.styl index 00044b4e..8984db74 100644 --- a/browser/styles/mixins/marked.styl +++ b/browser/styles/mixins/marked.styl @@ -6,7 +6,7 @@ marked() background-color alpha(red, 0.1) color darken(red, 15%) padding 5px - margin -5px + margin 5px 0 border-radius 5px sup position relative @@ -116,9 +116,7 @@ marked() border solid 1px alpha(borderColor, 0.3) border-radius 4px font-size 0.9em - color black text-decoration none - background-color #F6F6F6 margin-right 2px *:not(a.lineAnchor) + code margin-left 2px @@ -128,14 +126,15 @@ marked() border-radius 5px overflow-x auto margin 0 0 15px - background-color #F6F6F6 line-height 1.35em &>code margin 0 padding 0 border none border-radius 0 - color black + &>pre + border none + margin -5px table width 100% margin 15px 0 25px diff --git a/browser/styles/theme/dark.styl b/browser/styles/theme/dark.styl new file mode 100644 index 00000000..9c593dd9 --- /dev/null +++ b/browser/styles/theme/dark.styl @@ -0,0 +1,460 @@ +@import '../vars' + +themeDarkBackground = darken(#21252B, 10%) +themeDarkModal = darken(#21252B, 10%) +themeDarkList = #282C34 +themeDarkPreview = #282C34 +themeDarkSidebar = darken(#21252B, 10%) +themeDarkText = #DDDDDD +themeDarkBorder = lighten(themeDarkBackground, 20%) +themeDarkTopicColor = #369dcd +themeDarkTooltip = rgba(0, 0, 0, 0.7) +themeDarkFocusText = #FFFFFF +themeDarkFocusButton = lighten(themeDarkTopicColor, 30%) +themeDarkBoxShadow = alpha(lighten(themeDarkTopicColor, 10%), 0.4); +themeDarkTableOdd = themeDarkPreview +themeDarkTableEven = darken(themeDarkPreview, 10%) +themeDarkTableHead = themeDarkTableEven +themeDarkTableBorder = themeDarkBorder +themeDarkModalButtonDefault = themeDarkPreview +themeDarkModalButtonDanger = #BF360C + +body[data-theme="dark"] + background-color themeDarkBackground + + .Main + .ArticleNavigator .userInfo .settingBtn .tooltip, + .ArticleNavigator .ArticleNavigator-folders .ArticleNavigator-folders-header .addBtn .tooltip, + .ArticleTopBar>.ArticleTopBar-left>.ArticleTopBar-left-search .tooltip, + .ArticleTopBar>.ArticleTopBar-left .ArticleTopBar-left-control button.ArticleTopBar-left-control-new-post-button .tooltip + .ArticleTopBar>.ArticleTopBar-right>button .tooltip, + .ArticleTopBar>.ArticleTopBar-right>.ArticleTopBar-right-links-button-dropdown, + .ArticleDetail .ArticleDetail-info .ArticleDetail-info-control>button .tooltip, + .ArticleDetail .ArticleDetail-info .ArticleDetail-info-control .ShareButton-open-button .tooltip { + background-color themeDarkTooltip + } + + .ArticleNavigator + border-color lighten(themeDarkBorder, 10%) + background-color themeDarkSidebar + + .userInfo + border-color themeDarkBorder + + .userName + color themeDarkText + + .ArticleNavigator-folders + border-color lighten(themeDarkBorder, 10%) + background-color themeDarkSidebar + + .ArticleNavigator-folders-header + border-color themeDarkBorder + + .title + color themeDarkText + + .folderList, + .folderList>button + color themeDarkText + + .folderList>button + transition 0.1s + + &:hover + background-color lighten(themeDarkSidebar, 10%) + + &.active, + $:active + background-color darken(brandColor, 15%) + + .userInfo .settingBtn, + .ArticleNavigator-folders .ArticleNavigator-folders-header .addBtn + transition 0.1s + color themeDarkText + border none + background-color lighten(themeDarkBackground, 10%) + + .userInfo .settingBtn:hover, + .ArticleNavigator-folders .ArticleNavigator-folders-header .addBtn:hover + background-color themeDarkTopicColor + + .userInfo .settingBtn:focus, + .ArticleNavigator-folders .ArticleNavigator-folders-header .addBtn:focus + background-color darken(themeDarkTopicColor, 20%) + + .ArticleTopBar + color themeDarkText + background-color themeDarkBackground + + .ArticleTopBar-left + .ArticleTopBar-left-search input + color themeDarkText + background-color lighten(themeDarkBackground, 10%) + + .ArticleTopBar-left-control button.ArticleTopBar-left-control-new-post-button + color themeDarkText + background-color lighten(themeDarkBackground, 10%) + + &:hover + color themeDarkText + background-color themeDarkTopicColor + + &:focus + color themeDarkText + background-color darken(themeDarkTopicColor, 20%) + + .ArticleTopBar-right + &>button + color themeDarkText + border none + background-color lighten(themeDarkBackground, 10%) + + &:hover + color themeDarkText + background-color themeDarkTopicColor + + &:focus + color themeDarkText + background-color darken(themeDarkTopicColor, 20%) + + .ArticleList + color themeDarkText + border-color themeDarkBorder + background-color themeDarkList + + .ArticleList-item + color themeDarkText + background-color themeDarkList + + &:hover + background-color lighten(themeDarkList, 5%) + + .ArticleList-item-top + .folderName + color darken(themeDarkText, 15%) + + .divider + border-color themeDarkBorder + + .ArticleDetail + color themeDarkText + border-color themeDarkBorder + background-color themeDarkBackground + + .ArticleDetail-info + .ArticleDetail-info-folder + color themeDarkText + background-color lighten(themeDarkBackground, 10%) + + .ArticleDetail-info-row2 .TagSelect .TagSelect-tags + border-color themeDarkBorder + background-color themeDarkBackground + + input + color themeDarkText + + .ArticleDetail-info-control + &>button, + & .ShareButton-open-button + transition 0.1s + color themeDarkText + border none + background-color lighten(themeDarkBackground, 10%) + + &>button:hover, + & .ShareButton-open-button:hover + background-color themeDarkTopicColor + + &>button:focus, + & .ShareButton-open-button:focus + background-color darken(themeDarkTopicColor, 20%) + + & .ShareButton-dropdown + color themeDarkText + box-shadow 0px 0px 10px 1px themeDarkBoxShadow; + border 1px solid themeDarkBorder; + background-color themeDarkBackground + + & .ShareButton-dropdown>button + color themeDarkText + + &:hover + background-color darken(themeDarkTopicColor, 20%) + + .ArticleDetail-panel + border-color themeDarkBackground + + .ArticleDetail-panel-header, + .ArticleDetail-panel-header .ArticleDetail-panel-header-title input + color themeDarkText + border-color themeDarkBorder + background-color themeDarkPreview + + .ArticleEditor + .CodeEditor + border-color themeDarkBorder + border-radius 0 + + &>.ArticleDetail-panel-header .ArticleDetail-panel-header-mode + transition 0.1s + color themeDarkText + background-color lighten(themeDarkBackground, 10%) + + input + color themeDarkText + + &.idle + border-color themeDarkBorder + background-color themeDarkPreview + + &.idle:hover + background-color themeDarkTopicColor + + &.edit .ModeSelect-options + color themeDarkText + border-color themeDarkBackground + background-color themeDarkBackground + + .ModeSelect-options-item + &:hover + color lighten(themeDarkText, 100%) + background-color darken(themeDarkTopicColor, 20%) + + .ModalBase + .modal + color themeDarkText + background-color themeDarkModal + box-shadow 0px 0px 10px 1px themeDarkBoxShadow; + + input + color themeDarkText + border-color lighten(themeDarkBackground, 10%) + background-color lighten(themeDarkBackground, 10%) + + &:hover + border-color themeDarkBorder + + &:focus + border-color themeDarkTopicColor + + button + &:hover + background-color lighten(themeDarkBackground, 10%) + + .CreateNewFolder.modal + .closeBtn + transition 0.1s + border-radius 24px + color themeDarkText + + &:hover + background-color darken(#BF360C, 10%) + + .confirmBtn + background-color darken(brandColor, 10%) + + &:hover + background-color brandColor + + .DeleteArticleModal.modal + .control + button + transition 0.1s + color themeDarkText + border-color lighten(themeDarkModalButtonDefault, 20%) + background-color themeDarkModalButtonDefault + + &:hover + background-color: lighten(themeDarkModalButtonDefault, 10%) + + &:focus + border-color themeDarkTopicColor + + &.danger + background-color themeDarkModalButtonDanger + border-color lighten(themeDarkModalButtonDanger, 30%) + + &:hover + background-color: lighten(themeDarkModalButtonDanger, 10%) + + &:focus + border-color lighten(themeDarkModalButtonDanger, 50%) + + .Preferences.modal + .sectionInput input, + .sectionSelect select + .sectionMultiSelect .sectionMultiSelect-input select + color themeDarkText + border-color lighten(themeDarkBackground, 10%) + background-color lighten(themeDarkBackground, 10%) + + &:hover + border-color themeDarkBorder + + &:focus + border-color themeDarkTopicColor + + .header + border-color themeDarkBorder + background-color darken(themeDarkModal, 40%) + + .nav + border-color themeDarkBorder + background-color darken(themeDarkModal, 20%) + + &>button + &:hover + color themeDarkFocusText + background-color lighten(themeDarkModal, 10%) + + &.active, + &:active + background-color darken(brandColor, 15%) + + .section + border-color themeDarkBorder + + &>.content + &.AppSettingTab + .description + code + color themeDarkText + border-color darken(themeDarkBorder, 10%) + background-color lighten(themeDarkPreview, 5%) + + &.FolderSettingTab + .folderTable + &>div + border-color themeDarkBorder + + &:last-child + border-color transparent + + &>div.FolderRow + .sortBtns button + transition 0.1s + color themeDarkText + + &:hover + color themeDarkFocusButton + + .folderColor + &>button, + .options + color themeDarkText + border-color themeDarkBorder + + &>button + border-color lighten(themeDarkBackground, 10%) + background-color lighten(themeDarkBackground, 10%) + + &:hover + border-color themeDarkBorder + + &:focus + border-color themeDarkTopicColor + + .options + background-color themeDarkBackground + + &>div.FolderRow .folderName input, + &>div.newFolder .folderName input + color themeDarkText + border-color lighten(themeDarkBackground, 10%) + background-color lighten(themeDarkBackground, 10%) + + &:hover + border-color themeDarkBorder + + &:focus + border-color themeDarkTopicColor + + .folderControl + button + transition 0.1s + color themeDarkText + + &:hover + color themeDarkFocusButton + + .Finder + .FinderInput + color themeDarkText + border-color themeDarkBorder + background-color themeDarkBackground + + input + color themeDarkText + border-color lighten(themeDarkBackground, 10%) + background-color lighten(themeDarkBackground, 10%) + + &:focus + border-color themeDarkTopicColor + + .FinderList + color themeDarkText + border-color themeDarkBorder + background-color themeDarkList + + .divider + border-color themeDarkBorder + + .FinderDetail + color themeDarkText + border-color themeDarkBorder + background-color themeDarkPreview + box-shadow 0px 0px 10px 0 darken(themeDarkBorder, 20%); + + .header + border-color themeDarkBorder + + .right + .clipboardBtn + transition 0.1s + + &:hover + color themeDarkFocusButton + + .tooltip + background-color themeDarkTooltip + + .ArticleDetail-panel + border-radius 0 + + // Markdown Preview + .Finder .FinderDetail .content, + .ArticleDetail .ArticleDetail-panel .ArticleEditor + .MarkdownPreview + color themeDarkText + border-color themeDarkBorder + background-color themeDarkPreview + + a:hover + background-color alpha(lighten(brandColor, 30%), 0.2) !important + + code + border-color darken(themeDarkBorder, 10%) + background-color lighten(themeDarkPreview, 5%) + + pre + code + background-color transparent + + table + thead + tr + background-color themeDarkTableHead + th + border-color themeDarkTableBorder + &:last-child + border-right solid 1px themeDarkTableBorder + tbody + tr:nth-child(2n + 1) + background-color themeDarkTableOdd + tr:nth-child(2n) + background-color themeDarkTableEven + td + border-color themeDarkTableBorder + &:last-child + border-right solid 1px themeDarkTableBorder diff --git a/gruntfile.js b/gruntfile.js index e2cb3cfc..5496c490 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -4,6 +4,8 @@ const packager = require('electron-packager') const fs = require('fs') const merge = require('merge-stream') +const WIN = process.platform === 'win32' + module.exports = function (grunt) { var auth_code try { @@ -55,7 +57,9 @@ module.exports = function (grunt) { grunt.initConfig(initConfig) grunt.loadNpmTasks('grunt-electron-installer') - grunt.loadNpmTasks('grunt-electron-installer-debian') + if (!WIN) { + grunt.loadNpmTasks('grunt-electron-installer-debian') + } grunt.registerTask('copy', function () { var done = this.async() @@ -116,11 +120,11 @@ module.exports = function (grunt) { version: grunt.config.get('pkg.config.electron-version'), 'app-version': grunt.config.get('pkg.version'), 'app-bundle-id': 'com.maisin.boost', - asar: true, + asar: false, prune: true, overwrite: true, out: path.join(__dirname, 'dist'), - ignore: /submodules\/ace\/(?!src-min)|submodules\/ace\/(?=src-min-noconflict)|node_modules\/devicon\/icons|dist|^\/browser|^\/secret|\.babelrc|\.gitignore|^\/\.gitmodules|^\/gruntfile|^\/readme.md|^\/webpack|^\/appdmg\.json/ + ignore: /submodules\/ace\/(?!src-min)|submodules\/ace\/(?=src-min-noconflict)|node_modules\/devicon\/icons|dist|^\/browser|^\/secret|\.babelrc|\.gitignore|^\/\.gitmodules|^\/gruntfile|^\/readme.md|^\/webpack|^\/appdmg\.json|^\/node_modules\/grunt/ } switch (platform) { case 'win': diff --git a/lib/config.js b/lib/config.js index e79f2bec..8e631e47 100644 --- a/lib/config.js +++ b/lib/config.js @@ -12,7 +12,10 @@ const defaultConfig = { 'preview-font-size': '14', 'preview-font-family': 'Lato', 'switch-preview': 'blur', - 'disable-direct-write': false + 'disable-direct-write': false, + 'theme-ui': 'light', + 'theme-code': 'xcode', + 'theme-syntax': 'xcode' } const configFile = 'config.json' @@ -76,4 +79,3 @@ app.on('ready', function () { applyConfig() }) }) - diff --git a/lib/finder-menu.js b/lib/finder-menu.js index bce97da0..dbc743f6 100644 --- a/lib/finder-menu.js +++ b/lib/finder-menu.js @@ -2,7 +2,7 @@ const electron = require('electron') const BrowserWindow = electron.BrowserWindow const OSX = process.platform === 'darwin' -const WIN = process.platform === 'win32' +// const WIN = process.platform === 'win32' var edit = { label: 'Edit', diff --git a/lib/finder.html b/lib/finder.html index 50412a5d..f5ceb6f8 100644 --- a/lib/finder.html +++ b/lib/finder.html @@ -9,7 +9,7 @@ - + diff --git a/lib/main-app.js b/lib/main-app.js index 11f0125f..278ad34c 100644 --- a/lib/main-app.js +++ b/lib/main-app.js @@ -288,6 +288,14 @@ app.on('ready', function () { }) break case 'linux': + if (process.env.DESKTOP_SESSION === 'cinnamon') { + finderWindow = require('./finder-window') + finderWindow.on('close', function (e) { + if (appQuit) return true + e.preventDefault() + finderWindow.hide() + }) + } // Do nothing. } diff --git a/lib/main-menu.js b/lib/main-menu.js index 6accf63b..767f5ac6 100644 --- a/lib/main-menu.js +++ b/lib/main-menu.js @@ -4,7 +4,7 @@ const shell = electron.shell const mainWindow = require('./main-window') const OSX = process.platform === 'darwin' -const WIN = process.platform === 'win32' +// const WIN = process.platform === 'win32' const LINUX = process.platform === 'linux' var boost = { @@ -201,7 +201,7 @@ var help = { }, { label: 'Changelog', - click: function () { shell.openExternal('https://github.com/BoostIO/boost-releases/blob/master/changelog.md') } + click: function () { shell.openExternal('https://github.com/BoostIO/boost-releases') } } ] } diff --git a/lib/main.html b/lib/main.html index 3d032869..49b390d4 100644 --- a/lib/main.html +++ b/lib/main.html @@ -6,7 +6,7 @@ - + Boostnote @@ -56,6 +56,7 @@
+ diff --git a/package.json b/package.json index b2a66111..7ee4a0e0 100644 --- a/package.json +++ b/package.json @@ -26,23 +26,28 @@ "electron" ], "author": "Dick Choi (https://github.com/Rokt33r)", + "contributors": [ + "dojineko (https://github.com/dojineko)", + "Romain Bazile (https://github.com/gromain)", + "Bruno Paz (https://github.com/brpaz)" + ], "bugs": { "url": "https://github.com/BoostIO/Boostnote/issues" }, "homepage": "https://b00st.io", "dependencies": { + "@rokt33r/markdown-it-math": "^4.0.1", "@rokt33r/node-ipc": "^5.0.4", "@rokt33r/sanitize-html": "^1.11.2", "devicon": "^2.0.0", "electron-gh-releases": "^2.0.2", "font-awesome": "^4.3.0", "fs-jetpack": "^0.7.0", - "highlight.js": "^8.9.1", + "highlight.js": "^9.3.0", "lodash": "^3.10.1", - "markdown-it": "^4.4.0", + "markdown-it": "^6.0.1", "markdown-it-checkbox": "^1.1.0", - "markdown-it-emoji": "^1.1.0", - "markdown-it-math": "^3.0.2", + "markdown-it-emoji": "^1.1.1", "md5": "^2.0.0", "moment": "^2.10.3", "season": "^5.3.0", @@ -62,7 +67,6 @@ "electron-release": "^2.2.0", "grunt": "^0.4.5", "grunt-electron-installer": "^1.2.0", - "grunt-electron-installer-debian": "^0.2.0", "history": "^1.17.0", "nib": "^1.1.0", "react": "^0.14.3", @@ -70,16 +74,21 @@ "react-dom": "^0.14.3", "react-redux": "^4.0.6", "redux": "^3.0.5", - "standard": "^5.3.1", + "standard": "^6.0.8", "style-loader": "^0.12.4", "stylus": "^0.52.4", "stylus-loader": "^1.3.1", "webpack": "^1.12.2", "webpack-dev-server": "^1.12.0" }, + "optionalDependencies": { + "grunt-electron-installer-debian": "^0.2.0" + }, "optional": false, "standard": { - "ignore": [], + "ignore": [ + "submodules" + ], "globals": [ "localStorage" ] diff --git a/readme.md b/readme.md index 886c1535..a66d8f9c 100644 --- a/readme.md +++ b/readme.md @@ -125,6 +125,12 @@ grunt zip:osx [Rokt33r(Dick Choi of MAISIN&CO.)](https://github.com/rokt33r) +## Contributors + +- [dojineko](https://github.com/dojineko) +- [Romain Bazile](https://github.com/gromain) +- [Bruno Paz](https://github.com/brpaz) + ## Copyright & License Copyright (C) 2016 MAISIN&CO. diff --git a/webpack-skeleton.js b/webpack-skeleton.js index 1cec52df..5638cd82 100644 --- a/webpack-skeleton.js +++ b/webpack-skeleton.js @@ -37,7 +37,7 @@ var config = { 'highlight.js', 'markdown-it-emoji', 'fs-jetpack', - 'markdown-it-math', + '@rokt33r/markdown-it-math', '@rokt33r/sanitize-html', 'markdown-it-checkbox', 'season',