diff --git a/app/resources/checked/checked.png b/app/resources/checked/checked.png new file mode 100755 index 0000000..c222c48 Binary files /dev/null and b/app/resources/checked/checked.png differ diff --git a/app/resources/checked/checked@2x.png b/app/resources/checked/checked@2x.png new file mode 100755 index 0000000..feb7170 Binary files /dev/null and b/app/resources/checked/checked@2x.png differ diff --git a/app/resources/checked/checked@3x.png b/app/resources/checked/checked@3x.png new file mode 100755 index 0000000..c55d6d2 Binary files /dev/null and b/app/resources/checked/checked@3x.png differ diff --git a/app/resources/close/close.png b/app/resources/close/close.png new file mode 100755 index 0000000..9b67ce6 Binary files /dev/null and b/app/resources/close/close.png differ diff --git a/app/resources/close/close@2x.png b/app/resources/close/close@2x.png new file mode 100755 index 0000000..591c942 Binary files /dev/null and b/app/resources/close/close@2x.png differ diff --git a/app/resources/close/close@3x.png b/app/resources/close/close@3x.png new file mode 100755 index 0000000..790071f Binary files /dev/null and b/app/resources/close/close@3x.png differ diff --git a/app/resources/not-checked/not-checked.png b/app/resources/not-checked/not-checked.png new file mode 100755 index 0000000..1caea70 Binary files /dev/null and b/app/resources/not-checked/not-checked.png differ diff --git a/app/resources/not-checked/not-checked@2x.png b/app/resources/not-checked/not-checked@2x.png new file mode 100755 index 0000000..8b1f19f Binary files /dev/null and b/app/resources/not-checked/not-checked@2x.png differ diff --git a/app/resources/not-checked/not-checked@3x.png b/app/resources/not-checked/not-checked@3x.png new file mode 100755 index 0000000..e9042de Binary files /dev/null and b/app/resources/not-checked/not-checked@3x.png differ diff --git a/app/view/app-component.js b/app/view/app-component.js index 3c81a8c..49e8daa 100644 --- a/app/view/app-component.js +++ b/app/view/app-component.js @@ -1,14 +1,25 @@ import React from 'react'; import ClipList from './clip-list'; import Header from './header'; +import SettingView from './settingView'; import autobind from 'autobind-decorator'; +import setting from '../setting.json'; +import {ipcRenderer} from 'electron'; +import update from 'react-addons-update'; @autobind export default class AppComponent extends React.Component { constructor() { super(); this.state = { - enableDelete: false + enableDelete: false, + currentScene: 'clipList', + // TODO : change it using router later + appSetting: { + launchOnStartup: false, + showNotification: false, + enableTranslation: setting.enableServiceHook + } }; } @@ -16,11 +27,31 @@ export default class AppComponent extends React.Component { this.setState({enableDelete: !this.state.enableDelete}); } + setCurrentScene(scene) { + this.setState({currentScene: scene}); + } + + toggleEnableTranslation() { + ipcRenderer.send('enable-translate', !this.state.appSetting.enableTranslation); + this.setState({ + appSetting: update(this.state.appSetting, + {enableTranslation: {$set: !this.state.appSetting.enableTranslation}} + ) + }); + } + render() { return ( -
-
- +
+
+ {this.state.currentScene === 'clipList' ? + : + + }
); } diff --git a/app/view/clip-list.js b/app/view/clip-list.js index 2f9fee9..6ab2b1d 100644 --- a/app/view/clip-list.js +++ b/app/view/clip-list.js @@ -9,7 +9,9 @@ export default class ClipContainer extends React.Component { super(props); this.state = { clips: [], - checkedClips: [] + checkedClips: [], + launchOnStartup: false, + showNotification: false }; } @@ -28,6 +30,10 @@ export default class ClipContainer extends React.Component { }); } + toggleEnableTranslation() { + this.setState({enableTranslation: !this.state.enableTranslation}); + } + loadClips() { this.setState({clips: ipcRenderer.sendSync('load-clips')}); } @@ -45,7 +51,14 @@ export default class ClipContainer extends React.Component { renderDeleteBar() { return ( -
+
@@ -85,22 +98,74 @@ export default class ClipContainer extends React.Component { ); } // TODO : refactoring component + + renderDeleteOption(isChecked, source) { + return ( +
+
+
+
+ { + if (isChecked) { + this.deleteCheckedClips(source); + return; + } + this.addCheckedClips(source); + }}/> +
+
+
+ {this.props.enableTranslation &&
} +
+ ); + } + render() { return (
- {this.props.enableDelete && this.renderDeleteBar() } + {this.props.enableDelete && this.renderDeleteBar()} +
+ {this.props.enableTranslation && !this.props.enableDelete && + + } {this.state.clips.map((content, i) => - = 0} - /> +
+ { + this.props.enableDelete && + this.renderDeleteOption( + this.state.checkedClips.indexOf(content.source) >= 0, content.source + ) + } +
+ +
+
)}
diff --git a/app/view/clip.js b/app/view/clip.js index 6ee8b9c..1131e4d 100644 --- a/app/view/clip.js +++ b/app/view/clip.js @@ -1,5 +1,4 @@ import React from 'react'; -import {ipcRenderer} from 'electron'; import autobind from 'autobind-decorator'; @autobind @@ -8,50 +7,17 @@ export default class Clip extends React.Component { super(props); } - deleteContents() { - this.props.deleteLog(this.props.index); - ipcRenderer.send('delete-contents', this.props.source); - ipcRenderer.on('delete-result', () => { - // TODO : alert message - }); - } - - render() { + renderSingleWord() { return (
- { - this.props.enableDelete && -
-
-
- { - if (this.props.isChecked) { - this.props.deleteCheckedClips(this.props.source); - return; - } - this.props.addCheckedClips(this.props.source); - }}/> -
-
-
- }
-
+
); } + + renderDoubleWord() { + return ( +
+
+
+
+
+
+
+
+
+
+
{this.props.source}
+
+
+
+
+
+
+
+
+
+
{this.props.google}
+
+
+
+
+
+
+
+
+
+
+
+ ); + } + + render() { + return ( +
+ { this.props.enableTranslation ? this.renderDoubleWord() : this.renderSingleWord() } +
+ ); + } } diff --git a/app/view/header.js b/app/view/header.js index 209554a..ffc6c99 100644 --- a/app/view/header.js +++ b/app/view/header.js @@ -15,19 +15,37 @@ export default class header extends React.Component { style={{height: 12, width: 12}}/>
-
- Text Logger | Beta version +
+ Text Logger + | Beta version
+ {this.props.currentScene === 'clipList' ? + onClick={this.props.setDeleteEnabled}/> :
+ }
- + {this.props.currentScene === 'clipList' ? + // TODO : change it using router later + this.props.setCurrentScene('setting')}/> : + this.props.setCurrentScene('clipList')}/> + }
diff --git a/app/view/popup.html b/app/view/popup.html index f54da7d..13690bc 100644 --- a/app/view/popup.html +++ b/app/view/popup.html @@ -2,11 +2,18 @@ electron es6 react boilerplate + + diff --git a/app/view/reactSelect.css b/app/view/reactSelect.css new file mode 100644 index 0000000..40a534a --- /dev/null +++ b/app/view/reactSelect.css @@ -0,0 +1,374 @@ +/** + * React Select + * ============ + * Created by Jed Watson and Joss Mackison for KeystoneJS, http://www.keystonejs.com/ + * https://twitter.com/jedwatson https://twitter.com/jossmackison https://twitter.com/keystonejs + * MIT License: https://github.com/JedWatson/react-select +*/ +.Select { + position: relative; +} +.Select, +.Select div, +.Select input, +.Select span { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.Select.is-disabled > .Select-control { + background-color: #f9f9f9; +} +.Select.is-disabled > .Select-control:hover { + box-shadow: none; +} +.Select.is-disabled .Select-arrow-zone { + cursor: default; + pointer-events: none; + opacity: 0.35; +} +.Select-control { + background-color: #ffffff; + border-color: #dce0e2; + border-radius: 1px; + border: 1px solid #ccc; + color: #333; + cursor: default; + display: table; + border-spacing: 0; + border-collapse: separate; + height: 26px; + outline: none; + overflow: hidden; + position: relative; + width: 100%; +} +.Select-control:hover { + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06); +} +.Select-control .Select-input:focus { + outline: none; +} +.is-searchable.is-open > .Select-control { + cursor: text; +} +.is-open > .Select-control { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + background: #fff; + border-color: #b3b3b3 #ccc #d9d9d9; +} +.is-open > .Select-control > .Select-arrow { + border-color: transparent transparent #999; + border-width: 0 5px 5px; +} +.is-searchable.is-focused:not(.is-open) > .Select-control { + cursor: text; +} +.is-focused:not(.is-open) > .Select-control { + border-color: #007eff; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 0 3px rgba(0, 126, 255, 0.1); +} +.Select-placeholder, +.Select--single > .Select-control .Select-value { + bottom: 0; + color: #aaa; + left: 0; + line-height: 24px; + padding-left: 10px; + padding-right: 10px; + position: absolute; + right: 0; + top: 0; + font-size: 12px; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.has-value.Select--single > .Select-control .Select-value .Select-value-label, +.has-value.is-pseudo-focused.Select--single > .Select-control .Select-value .Select-value-label { + color: #333; +} +.has-value.Select--single > .Select-control .Select-value a.Select-value-label, +.has-value.is-pseudo-focused.Select--single > .Select-control .Select-value a.Select-value-label { + cursor: pointer; + text-decoration: none; +} +.has-value.Select--single > .Select-control .Select-value a.Select-value-label:hover, +.has-value.is-pseudo-focused.Select--single > .Select-control .Select-value a.Select-value-label:hover, +.has-value.Select--single > .Select-control .Select-value a.Select-value-label:focus, +.has-value.is-pseudo-focused.Select--single > .Select-control .Select-value a.Select-value-label:focus { + color: #007eff; + outline: none; + text-decoration: underline; +} +.Select-input { + height: 24px; + padding-left: 10px; + padding-right: 10px; + vertical-align: middle; +} +.Select-input > input { + width: 100%; + background: none transparent; + border: 0 none; + box-shadow: none; + cursor: default; + display: inline-block; + font-family: inherit; + font-size: inherit; + margin: 0; + outline: none; + line-height: 14px; + /* For IE 8 compatibility */ + padding: 8px 0 12px; + /* For IE 8 compatibility */ + -webkit-appearance: none; +} +.is-focused .Select-input > input { + cursor: text; +} +.has-value.is-pseudo-focused .Select-input { + opacity: 0; +} +.Select-control:not(.is-searchable) > .Select-input { + outline: none; +} +.Select-loading-zone { + cursor: pointer; + display: table-cell; + position: relative; + text-align: center; + vertical-align: middle; + width: 16px; +} +.Select-loading { + -webkit-animation: Select-animation-spin 400ms infinite linear; + -o-animation: Select-animation-spin 400ms infinite linear; + animation: Select-animation-spin 400ms infinite linear; + width: 16px; + height: 16px; + box-sizing: border-box; + border-radius: 50%; + border: 2px solid #ccc; + border-right-color: #333; + display: inline-block; + position: relative; + vertical-align: middle; +} +.Select-clear-zone { + -webkit-animation: Select-animation-fadeIn 200ms; + -o-animation: Select-animation-fadeIn 200ms; + animation: Select-animation-fadeIn 200ms; + color: #999; + cursor: pointer; + display: table-cell; + position: relative; + text-align: center; + vertical-align: middle; + width: 17px; +} +.Select-clear-zone:hover { + color: #D0021B; +} +.Select-clear { + display: inline-block; + font-size: 18px; + line-height: 1; +} +.Select--multi .Select-clear-zone { + width: 17px; +} +.Select-arrow-zone { + cursor: pointer; + display: table-cell; + position: relative; + text-align: center; + vertical-align: middle; + width: 25px; + padding-right: 5px; +} +.Select-arrow { + border-color: #999 transparent transparent; + border-style: solid; + border-width: 5px 5px 2.5px; + display: inline-block; + height: 0; + width: 0; +} +.is-open .Select-arrow, +.Select-arrow-zone:hover > .Select-arrow { + border-top-color: #666; +} +.Select--multi .Select-multi-value-wrapper { + display: inline-block; +} +.Select .Select-aria-only { + display: inline-block; + height: 1px; + width: 1px; + margin: -1px; + clip: rect(0, 0, 0, 0); + overflow: hidden; +} +@-webkit-keyframes Select-animation-fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} +@keyframes Select-animation-fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} +.Select-menu-outer { + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; + background-color: #fff; + border: 1px solid #ccc; + border-top-color: #e6e6e6; + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06); + box-sizing: border-box; + margin-top: -1px; + max-height: 200px; + position: absolute; + top: 100%; + width: 100%; + z-index: 1; + -webkit-overflow-scrolling: touch; +} +.Select-menu { + max-height: 198px; + overflow-y: auto; +} +.Select-option { + box-sizing: border-box; + font-size: 10px; + background-color: #fff; + color: #666666; + cursor: pointer; + display: block; + padding: 8px 10px; +} +.Select-option:last-child { + border-bottom-right-radius: 1px; + border-bottom-left-radius: 1px; +} +.Select-option.is-selected { + background-color: #f5faff; + /* Fallback color for IE 8 */ + background-color: rgba(0, 126, 255, 0.04); + color: #333; +} +.Select-option.is-focused { + background-color: #ebf5ff; + /* Fallback color for IE 8 */ + background-color: rgba(0, 126, 255, 0.08); + color: #333; +} +.Select-option.is-disabled { + color: #cccccc; + cursor: default; +} +.Select-noresults { + box-sizing: border-box; + color: #999999; + cursor: default; + display: block; + padding: 8px 10px; +} +.Select--multi .Select-input { + vertical-align: middle; + margin-left: 10px; + padding: 0; +} +.Select--multi.has-value .Select-input { + margin-left: 5px; +} +.Select--multi .Select-value { + background-color: #ebf5ff; + /* Fallback color for IE 8 */ + background-color: rgba(0, 126, 255, 0.08); + border-radius: 2px; + border: 1px solid #c2e0ff; + /* Fallback color for IE 8 */ + border: 1px solid rgba(0, 126, 255, 0.24); + color: #007eff; + display: inline-block; + font-size: 0.9em; + line-height: 1.4; + margin-left: 5px; + margin-top: 5px; + vertical-align: top; +} +.Select--multi .Select-value-icon, +.Select--multi .Select-value-label { + display: inline-block; + vertical-align: middle; +} +.Select--multi .Select-value-label { + border-bottom-right-radius: 2px; + border-top-right-radius: 2px; + cursor: default; + padding: 2px 5px; +} +.Select--multi a.Select-value-label { + color: #007eff; + cursor: pointer; + text-decoration: none; +} +.Select--multi a.Select-value-label:hover { + text-decoration: underline; +} +.Select--multi .Select-value-icon { + cursor: pointer; + border-bottom-left-radius: 2px; + border-top-left-radius: 2px; + border-right: 1px solid #c2e0ff; + /* Fallback color for IE 8 */ + border-right: 1px solid rgba(0, 126, 255, 0.24); + padding: 1px 5px 3px; +} +.Select--multi .Select-value-icon:hover, +.Select--multi .Select-value-icon:focus { + background-color: #d8eafd; + /* Fallback color for IE 8 */ + background-color: rgba(0, 113, 230, 0.08); + color: #0071e6; +} +.Select--multi .Select-value-icon:active { + background-color: #c2e0ff; + /* Fallback color for IE 8 */ + background-color: rgba(0, 126, 255, 0.24); +} +.Select--multi.is-disabled .Select-value { + background-color: #fcfcfc; + border: 1px solid #e3e3e3; + color: #333; +} +.Select--multi.is-disabled .Select-value-icon { + cursor: not-allowed; + border-right: 1px solid #e3e3e3; +} +.Select--multi.is-disabled .Select-value-icon:hover, +.Select--multi.is-disabled .Select-value-icon:focus, +.Select--multi.is-disabled .Select-value-icon:active { + background-color: #fcfcfc; +} +@keyframes Select-animation-spin { + to { + transform: rotate(1turn); + } +} +@-webkit-keyframes Select-animation-spin { + to { + -webkit-transform: rotate(1turn); + } +} diff --git a/app/view/settingView.js b/app/view/settingView.js new file mode 100644 index 0000000..2a73e55 --- /dev/null +++ b/app/view/settingView.js @@ -0,0 +1,143 @@ +import React from 'react'; +import autobind from 'autobind-decorator'; +import Select from 'react-select'; + +const options = [ + { value: 'one', label: 'One' }, + { value: 'two', label: 'Two' } +]; + +@autobind +export default class SettingView extends React.Component { + constructor(props) { + super(props); + } + + render() { + return ( +
+
+
+
+
Setting
+
+
+
+ +
+
+
Launch on startup
+
+
+
+
+ +
+
+
Show notifications
+
+
+
+
+ this.props.toggleEnableTranslation()} + style={{width: 12, height: 12}}/> +
+
+
Turn on translation
+
+
+
+
+
+ {}} + placeholder="Translation" + searchable={false} + /> +
+
+
+
+
+
+
Shortcuts
+
+
Reset
+
+
+
+
Copy
+
+
Ctrl + C
+
+
+
+
Save
+
+
Command + Ctrl + S
+
+
+
+
+
+ ); + } +} diff --git a/package.json b/package.json index 533b569..ca37b87 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,8 @@ "node-notifier": "^4.6.1", "react": "^15.4.1", "react-addons-update": "^15.4.1", - "react-dom": "^15.4.1" + "react-dom": "^15.4.1", + "react-select": "^1.0.0-rc.2" }, "devDependencies": { "babel-eslint": "^7.1.1",