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

Compare commits

..

24 Commits
0.2.2 ... 0.2.9

Author SHA1 Message Date
Rokt33r
06a54d451c Merge branch 'dev'
* dev:
  0.2.9 API server changed, bump electron version 0.31.0
2015-08-31 01:34:15 +09:00
Rokt33r
e317075815 0.2.9 API server changed, bump electron version 0.31.0 2015-08-31 01:33:32 +09:00
Rokt33r
45541a255b Merge branch 'dev'
* dev:
  - StylusでコンパイルされたCSSをCachingする(ロディングが短くなる) - Planet name changeのときにエラーハンドリング追加 + Bug fix - TeamのMemberを編集する場合、自分を編集することはできない - FinderにMarkdownのリンクがちゃんと外部に飛ぶように - Tray iconがちゃんと表示 - ArticleDetailのCodeアイコンがちゃんと表示されない
2015-08-30 05:31:13 +09:00
Rokt33r
3ab423d695 - StylusでコンパイルされたCSSをCachingする(ロディングが短くなる)
- Planet name changeのときにエラーハンドリング追加 + Bug fix
- TeamのMemberを編集する場合、自分を編集することはできない
- FinderにMarkdownのリンクがちゃんと外部に飛ぶように
- Tray iconがちゃんと表示
- ArticleDetailのCodeアイコンがちゃんと表示されない
2015-08-30 05:30:54 +09:00
Rokt33r
345d7b427a Merge branch 'dev'
* dev:
  Loading font 微調整
2015-08-26 18:27:42 +09:00
Rokt33r
de6d6b692e Loading font 微調整 2015-08-26 18:27:19 +09:00
Rokt33r
b2845e2284 Merge branch 'dev'
* dev:
  version 0.2.7  - Planet, Team作成の時Error message表示  - MarkdownのCode blockの背景を薄い灰色にする  - 権限なしのPlanetには  - SignUpに規約/Privacyの外部リンク追加  - Loading画面追加  - Font 添付(Lato regular)  - UserContainerでのTeam Label変更
2015-08-26 18:23:04 +09:00
Rokt33r
47383c347c version 0.2.7
- Planet, Team作成の時Error message表示
 - MarkdownのCode blockの背景を薄い灰色にする
 - 権限なしのPlanetには
 - SignUpに規約/Privacyの外部リンク追加
 - Loading画面追加
 - Font 添付(Lato regular)
 - UserContainerでのTeam Label変更
2015-08-26 18:22:46 +09:00
Rokt33r
4bda84d69c cleanup old files 2015-08-24 17:42:43 +09:00
Rokt33r
b510aa11f5 Merge branch 'dev'
* dev:
  fix bugs - ArticleList text overflow behaviour in Finder, PlanetContainer - No DevTools
2015-08-24 17:42:00 +09:00
Rokt33r
8dab6d5e04 fix bugs
- ArticleList text overflow behaviour in Finder, PlanetContainer
- No DevTools
2015-08-24 17:41:38 +09:00
Rokt33r
85f833c865 Merge branch 'dev'
* dev:
  v0.2.5 - bugfix - Alert message added(Private planet/Team member)

Conflicts:
	package.json
2015-08-24 13:46:32 +09:00
Rokt33r
15133d00c7 v0.2.5
- bugfix
- Alert message added(Private planet/Team member)
2015-08-24 13:45:28 +09:00
Rokt33r
b93990d10b bump version 2015-08-24 06:23:41 +09:00
Rokt33r
a0bcb8edbe Merge branch 'dev'
* dev:
  実装 - MemberがOwnerではないときにTeam設定ボターンを全部隠す
  v0.2.4 - Minor fix
  fix minor bug
2015-08-24 06:22:32 +09:00
Rokt33r
bfdf691bed 実装 - MemberがOwnerではないときにTeam設定ボターンを全部隠す 2015-08-24 06:22:16 +09:00
Rokt33r
f60856b998 v0.2.4 - Minor fix 2015-08-24 06:14:13 +09:00
Rokt33r
3308eeaf82 fix minor bug 2015-08-23 04:00:18 +09:00
Rokt33r
19930a2472 fix minor bug 2015-08-23 03:49:19 +09:00
Rokt33r
e75d95b1fc Merge branch 'dev'
* dev:
  実装 - PlanetArticleListへのAuto scroll追加
  実装 - tooltip (Refresh, Planet setting, Planet refresh, Edit article, Delete article, Contact)
  #14 改善適用 - アプリが立ち上がったら最初はmy planetが表示されるようにしたい - Noteがスクロールできない - Note行間がなくて読みづらい
  実装 - Hotkey
2015-08-23 03:42:40 +09:00
Rokt33r
4319711dc6 実装 - PlanetArticleListへのAuto scroll追加 2015-08-23 03:42:00 +09:00
Rokt33r
9712be909d 実装 - tooltip (Refresh, Planet setting, Planet refresh, Edit article, Delete article, Contact) 2015-08-23 03:05:30 +09:00
Rokt33r
04060ce252 #14 改善適用
- アプリが立ち上がったら最初はmy planetが表示されるようにしたい
- Noteがスクロールできない
- Note行間がなくて読みづらい
2015-08-23 00:52:03 +09:00
Rokt33r
da066fe694 実装 - Hotkey 2015-08-22 23:57:37 +09:00
69 changed files with 831 additions and 1767 deletions

3
.gitmodules vendored
View File

@@ -1,3 +1,6 @@
[submodule "browser/ace"]
path = browser/ace
url = https://github.com/ajaxorg/ace-builds.git
[submodule "browser/electron-stylus"]
path = browser/electron-stylus
url = https://github.com/Rokt33r/electron-stylus.git

BIN
Lato-Regular.ttf Normal file

Binary file not shown.

BIN
Lato-Regular.woff Normal file

Binary file not shown.

BIN
Lato-Regular.woff2 Normal file

Binary file not shown.

View File

@@ -2,10 +2,9 @@ var React = require('react/addons')
var CodeViewer = require('../../main/Components/CodeViewer')
var Markdown = require('../../main/Mixins/Markdown')
var MarkdownPreview = require('../../main/Components/MarkdownPreview')
module.exports = React.createClass({
mixins: [Markdown],
propTypes: {
currentArticle: React.PropTypes.object
},
@@ -28,7 +27,7 @@ module.exports = React.createClass({
<div className='FinderDetail'>
<div className='header'><i className='fa fa-file-text-o fa-fw'/> {article.title}</div>
<div className='content'>
<div className='marked' dangerouslySetInnerHTML={{__html: ' ' + this.markdown(article.content)}}></div>
<MarkdownPreview className='marked' content={article.content}/>
</div>
</div>
)

View File

@@ -8,6 +8,17 @@
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css" media="screen" title="no title" charset="utf-8">
<link rel="shortcut icon" href="favicon.ico">
<style>
@font-face {
font-family: 'Lato';
src: url('../../Lato-Regular.woff2') format('woff2'), /* Modern Browsers */
url('../../Lato-Regular.woff') format('woff'), /* Modern Browsers */
url('../../Lato-Regular.ttf') format('truetype');
font-style: normal;
font-weight: normal;
text-rendering: optimizeLegibility;
}
</style>
<script>
document.addEventListener('mousewheel', function(e) {
if(e.deltaY % 1 !== 0) {
@@ -47,14 +58,13 @@
}
});
}
require('electron-stylus')(__dirname + '/../styles/finder/index.styl')
</script>
</head>
<body>
<div id="content"></div>
<script src="../ace/src-min/ace.js"></script>
<script>
require('../electron-stylus')(__dirname + '/../styles/finder/index.styl', 'finderCss')
require('node-jsx').install({ harmony: true, extension: '.jsx' })
require('./index.jsx')
</script>

View File

@@ -4,12 +4,20 @@ var version = remote.getGlobal('version')
var React = require('react/addons')
var ExternalLink = require('../Mixins/ExternalLink')
var KeyCaster = require('../Mixins/KeyCaster')
module.exports = React.createClass({
mixins: [ExternalLink],
mixins: [ExternalLink, KeyCaster('aboutModal')],
propTypes: {
close: React.PropTypes.func
},
onKeyCast: function (e) {
switch (e.status) {
case 'closeModal':
this.props.close()
break
}
},
render: function () {
return (
<div className='AboutModal modal'>

View File

@@ -5,6 +5,8 @@ var LinkedState = require('../Mixins/LinkedState')
var Hq = require('../Services/Hq')
var KeyCaster = require('../Mixins/KeyCaster')
var UserStore = require('../Stores/UserStore')
var getOptions = function (input, callback) {
@@ -26,7 +28,7 @@ var getOptions = function (input, callback) {
}
module.exports = React.createClass({
mixins: [LinkedState],
mixins: [LinkedState, KeyCaster('addMemberModal')],
propTypes: {
team: React.PropTypes.object,
close: React.PropTypes.func
@@ -37,20 +39,35 @@ module.exports = React.createClass({
role: 'member'
}
},
handleSubmit: function () {
Hq
.addMember(this.props.team.name, {
userName: this.state.userName,
role: this.state.role
})
.then(function (res) {
console.log(res.body)
UserStore.Actions.addMember(res.body)
onKeyCast: function (e) {
switch (e.status) {
case 'closeModal':
this.props.close()
}.bind(this))
.catch(function (err) {
console.error(err)
})
break
case 'submitAddMemberModal':
this.handleSubmit()
break
}
},
handleSubmit: function () {
this.setState({errorMessage: null}, function () {
Hq
.addMember(this.props.team.name, {
userName: this.state.userName,
role: this.state.role
})
.then(function (res) {
console.log(res.body)
UserStore.Actions.addMember(res.body)
this.props.close()
}.bind(this))
.catch(function (err) {
console.error(err)
if (err.status === 403) {
this.setState({errorMessage: err.response.body.message})
}
}.bind(this))
})
},
handleChange: function (value) {
this.setState({userName: value})
@@ -76,6 +93,8 @@ module.exports = React.createClass({
role
</div>
{this.state.errorMessage != null ? (<p className='errorAlert'>{this.state.errorMessage}</p>) : null}
<button onClick={this.handleSubmit} className='submitButton'><i className='fa fa-check'/></button>
</div>
)

View File

@@ -2,19 +2,26 @@ var React = require('react')
var Hq = require('../Services/Hq')
var KeyCaster = require('../Mixins/KeyCaster')
var PlanetStore = require('../Stores/PlanetStore')
module.exports = React.createClass({
mixins: [KeyCaster('codeDeleteModal')],
propTypes: {
planet: React.PropTypes.object,
code: React.PropTypes.object,
close: React.PropTypes.func
},
componentDidMount: function () {
React.findDOMNode(this).focus()
},
stopPropagation: function (e) {
e.stopPropagation()
onKeyCast: function (e) {
switch (e.status) {
case 'submitCodeDeleteModal':
this.submit()
break
case 'closeModal':
this.props.close()
break
}
},
submit: function () {
var planet = this.props.planet

View File

@@ -7,13 +7,19 @@ module.exports = React.createClass({
code: React.PropTypes.object,
planet: React.PropTypes.object
},
componentDidMount: function () {
// TODO: Hacked!! should fix later
setTimeout(function () {
React.findDOMNode(this.refs.form.refs.description).focus()
}.bind(this), 1)
},
render: function () {
return (
<div className='CodeEditModal modal'>
<div className='modal-header'>
<h1>Edit Code</h1>
</div>
<CodeForm code={this.props.code} planet={this.props.planet} close={this.props.close}/>
<CodeForm ref='form' code={this.props.code} planet={this.props.planet} close={this.props.close}/>
</div>
)
}

View File

@@ -6,6 +6,7 @@ module.exports = React.createClass({
propTypes: {
code: React.PropTypes.string,
mode: React.PropTypes.string,
className: React.PropTypes.string,
onChange: React.PropTypes.func
},
componentDidMount: function () {
@@ -52,7 +53,7 @@ module.exports = React.createClass({
},
render: function () {
return (
<div ref='target'></div>
<div ref='target' className={this.props.className}></div>
)
}
})

View File

@@ -5,6 +5,7 @@ var Select = require('react-select')
var Hq = require('../Services/Hq')
var LinkedState = require('../Mixins/LinkedState')
var KeyCaster = require('../Mixins/KeyCaster')
var PlanetStore = require('../Stores/PlanetStore')
@@ -29,7 +30,7 @@ var getOptions = function (input, callback) {
}
module.exports = React.createClass({
mixins: [LinkedState],
mixins: [LinkedState, KeyCaster('codeForm')],
propTypes: {
planet: React.PropTypes.object,
close: React.PropTypes.func,
@@ -55,6 +56,16 @@ module.exports = React.createClass({
code: code
}
},
onKeyCast: function (e) {
switch (e.status) {
case 'submitCodeForm':
this.submit()
break
case 'closeModal':
this.props.close()
break
}
},
handleModeChange: function (selected) {
var code = this.state.code
code.mode = selected

View File

@@ -5,7 +5,8 @@ var ace = window.ace
module.exports = React.createClass({
propTypes: {
code: React.PropTypes.string,
mode: React.PropTypes.string
mode: React.PropTypes.string,
className: React.PropTypes.string
},
componentDidMount: function () {
var el = React.findDOMNode(this.refs.target)
@@ -46,7 +47,7 @@ module.exports = React.createClass({
},
render: function () {
return (
<div ref='target'></div>
<div ref='target' className={this.props.className}></div>
)
}
})

View File

@@ -1,11 +1,12 @@
var React = require('react')
var LinkedState = require('../Mixins/LinkedState')
var KeyCaster = require('../Mixins/KeyCaster')
var Hq = require('../Services/Hq')
module.exports = React.createClass({
mixins: [LinkedState],
mixins: [LinkedState, KeyCaster('contactModal')],
propTypes: {
close: React.PropTypes.func
},
@@ -18,6 +19,23 @@ module.exports = React.createClass({
}
}
},
onKeyCast: function (e) {
switch (e.status) {
case 'closeModal':
this.props.close()
break
case 'submitContactModal':
if (this.state.isSent) {
this.props.close()
return
}
this.sendEmail()
break
}
},
componentDidMount: function () {
React.findDOMNode(this.refs.title).focus()
},
sendEmail: function () {
Hq.sendEmail(this.state.mail)
.then(function (res) {
@@ -36,7 +54,7 @@ module.exports = React.createClass({
<div className='contactForm'>
<div className='modal-body'>
<div className='formField'>
<input valueLink={this.linkState('mail.title')} placeholder='Title'/>
<input ref='title' valueLink={this.linkState('mail.title')} placeholder='Title'/>
</div>
<div className='formField'>
<textarea valueLink={this.linkState('mail.content')} placeholder='Content'/>

View File

@@ -5,17 +5,19 @@ var React = require('react/addons')
var Hq = require('../Services/Hq')
var LinkedState = require('../Mixins/LinkedState')
var KeyCaster = require('../Mixins/KeyCaster')
var UserStore = require('../Stores/UserStore')
module.exports = React.createClass({
mixins: [LinkedState],
mixins: [LinkedState, KeyCaster('editProfileModal')],
propTypes: {
user: React.PropTypes.shape({
name: React.PropTypes.string,
profileName: React.PropTypes.string,
email: React.PropTypes.string
})
}),
close: React.PropTypes.func
},
getInitialState: function () {
var user = this.props.user
@@ -34,6 +36,13 @@ module.exports = React.createClass({
passwordSubmitStatus: null
}
},
onKeyCast: function (e) {
switch (e.status) {
case 'closeModal':
this.props.close()
break
}
},
selectTab: function (tabName) {
return function () {
this.setState({currentTab: tabName})

View File

@@ -71,16 +71,6 @@ module.exports = React.createClass({
openPlanetCreateModal: function () {
this.openModal(PlanetCreateModal, {transitionTo: this.transitionTo})
},
handleKeyDown: function (e) {
if (this.state.currentUser == null) return
if (e.metaKey && e.keyCode > 48 && e.keyCode < 58) {
var planet = this.state.currentUser.Planets[e.keyCode - 49]
if (planet != null) {
this.transitionTo('planet', {userName: planet.userName, planetName: planet.name})
}
e.preventDefault()
}
},
toggleProfilePopup: function () {
this.openProfilePopup()
},
@@ -96,6 +86,10 @@ module.exports = React.createClass({
handleLogoutClick: function () {
this.openModal(LogoutModal, {transitionTo: this.transitionTo})
},
switchPlanetByIndex: function (index) {
var planetProps = this.refs.planets.props.children[index - 1].props
this.transitionTo('planet', {userName: planetProps.userName, planetName: planetProps.planetName})
},
render: function () {
var params = this.getParams()
@@ -110,12 +104,12 @@ module.exports = React.createClass({
return team.Planets == null ? planets : planets.concat(team.Planets)
}, []))).map(function (planet, index) {
return (
<li key={planet.id} className={params.userName === planet.userName && params.planetName === planet.name ? 'active' : ''}>
<li userName={planet.userName} planetName={planet.name} key={planet.id} className={params.userName === planet.userName && params.planetName === planet.name ? 'active' : ''}>
<Link to='planet' params={{userName: planet.userName, planetName: planet.name}}>
{planet.name[0]}
<div className='planetTooltip'>{planet.userName}/{planet.name}</div>
</Link>
<div className='shortCut'>{index + 1}</div>
{index < 9 ? (<div className='shortCut'>{index + 1}</div>) : null}
</li>
)
})
@@ -128,12 +122,12 @@ module.exports = React.createClass({
<ProfileImage size='55' email={this.state.currentUser.email}/>
</button>
{popup}
<ul className='planetList'>
<ul ref='planets' className='planetList'>
{planets}
</ul>
<button onClick={this.openPlanetCreateModal} className='newPlanet'>
<i className='fa fa-plus'/>
<div className='newPlanetTooltip'>Create new planet</div>
<div className='tooltip'>Create new planet</div>
</button>
</div>
)

View File

@@ -15,34 +15,52 @@ module.exports = React.createClass({
}
},
componentDidMount: function () {
var codeButton = React.findDOMNode(this.refs.codeButton)
codeButton.addEventListener('keydown', this.handleKeyDown)
React.findDOMNode(this.refs.noteButton).addEventListener('keydown', this.handleKeyDown)
codeButton.focus()
},
stopPropagation: function (e) {
e.stopPropagation()
},
selectCodeTab: function () {
this.setState({currentTab: 'code'})
},
selectNoteTab: function () {
this.setState({currentTab: 'note'})
componentWillUnmount: function () {
React.findDOMNode(this.refs.codeButton).removeEventListener('keydown', this.handleKeyDown)
React.findDOMNode(this.refs.noteButton).removeEventListener('keydown', this.handleKeyDown)
},
handleKeyDown: function (e) {
if (e.keyCode === 37 && e.metaKey) {
this.selectCodeTab()
e.stopPropagation()
return
}
if (e.keyCode === 39 && e.metaKey) {
this.selectNoteTab()
e.stopPropagation()
return
}
if (e.keyCode === 9) {
if (this.state.currentTab === 'code') React.findDOMNode(this.refs.form.refs.description).focus()
else React.findDOMNode(this.refs.form.refs.title).focus()
e.preventDefault()
}
},
selectCodeTab: function () {
this.setState({currentTab: 'code'}, function () {
React.findDOMNode(this.refs.codeButton).focus()
})
},
selectNoteTab: function () {
this.setState({currentTab: 'note'}, function () {
React.findDOMNode(this.refs.noteButton).focus()
})
},
render: function () {
var modalBody
if (this.state.currentTab === 'code') {
modalBody = (
<CodeForm planet={this.props.planet} transitionTo={this.props.transitionTo} close={this.props.close}/>
<CodeForm ref='form' planet={this.props.planet} transitionTo={this.props.transitionTo} close={this.props.close}/>
)
} else {
modalBody = (
<NoteForm planet={this.props.planet} transitionTo={this.props.transitionTo} close={this.props.close}/>
<NoteForm ref='form' planet={this.props.planet} transitionTo={this.props.transitionTo} close={this.props.close}/>
)
}
@@ -50,7 +68,8 @@ module.exports = React.createClass({
<div className='LaunchModal modal'>
<div className='modal-header'>
<div className='modal-tab'>
<button className={this.state.currentTab === 'code' ? 'btn-primary active' : 'btn-default'} onClick={this.selectCodeTab}>Code</button><button className={this.state.currentTab === 'note' ? 'btn-primary active' : 'btn-default'} onClick={this.selectNoteTab}>Note</button>
<button ref='codeButton' className={this.state.currentTab === 'code' ? 'btn-primary active' : 'btn-default'} onClick={this.selectCodeTab}>Code</button>
<button ref='noteButton' className={this.state.currentTab === 'note' ? 'btn-primary active' : 'btn-default'} onClick={this.selectNoteTab}>Note</button>
</div>
</div>
{modalBody}

View File

@@ -2,11 +2,24 @@
var React = require('react')
var KeyCaster = require('../Mixins/KeyCaster')
module.exports = React.createClass({
mixins: [KeyCaster('logoutModal')],
propTypes: {
transitionTo: React.PropTypes.func,
close: React.PropTypes.func
},
onKeyCast: function (e) {
switch (e.status) {
case 'closeModal':
this.props.close()
break
case 'submitLogoutModal':
this.logout()
break
}
},
logout: function () {
localStorage.removeItem('currentUser')
localStorage.removeItem('token')

View File

@@ -2,16 +2,26 @@ var React = require('react')
var Hq = require('../Services/Hq')
var KeyCaster = require('../Mixins/KeyCaster')
var PlanetStore = require('../Stores/PlanetStore')
module.exports = React.createClass({
mixins: [KeyCaster('noteDeleteModal')],
propTypes: {
planet: React.PropTypes.object,
note: React.PropTypes.object,
close: React.PropTypes.func
},
componentDidMount: function () {
React.findDOMNode(this).focus()
onKeyCast: function (e) {
switch (e.status) {
case 'submitNoteDeleteModal':
this.submit()
break
case 'closeModal':
this.props.close()
break
}
},
submit: function () {
var planet = this.props.planet

View File

@@ -8,13 +8,19 @@ module.exports = React.createClass({
note: React.PropTypes.object,
planet: React.PropTypes.object
},
componentDidMount: function () {
// TODO: Hacked!! should fix later
setTimeout(function () {
React.findDOMNode(this.refs.form.refs.title).focus()
}.bind(this), 1)
},
render: function () {
return (
<div className='NoteEditModal modal'>
<div className='modal-header'>
<h1>Edit Note</h1>
</div>
<NoteForm note={this.props.note} planet={this.props.planet} close={this.props.close}/>
<NoteForm ref='form' note={this.props.note} planet={this.props.planet} close={this.props.close}/>
</div>
)
}

View File

@@ -1,11 +1,11 @@
var React = require('react/addons')
var ReactRouter = require('react-router')
var Select = require('react-select')
var Hq = require('../Services/Hq')
var LinkedState = require('../Mixins/LinkedState')
var Markdown = require('../Mixins/Markdown')
var KeyCaster = require('../Mixins/KeyCaster')
var PlanetStore = require('../Stores/PlanetStore')
@@ -34,7 +34,7 @@ var EDIT_MODE = 0
var PREVIEW_MODE = 1
module.exports = React.createClass({
mixins: [LinkedState, Markdown],
mixins: [LinkedState, Markdown, KeyCaster('noteForm')],
propTypes: {
planet: React.PropTypes.object,
close: React.PropTypes.func,
@@ -58,8 +58,15 @@ module.exports = React.createClass({
mode: EDIT_MODE
}
},
componentDidMount: function () {
React.findDOMNode(this.refs.title).focus()
onKeyCast: function (e) {
switch (e.status) {
case 'submitNoteForm':
this.submit()
break
case 'closeModal':
this.props.close()
break
}
},
handleTagsChange: function (selected, all) {
var note = this.state.note

View File

@@ -25,6 +25,7 @@ module.exports = React.createClass({
}
},
openEditModal: function () {
if (this.props.article == null) return
switch (this.props.article.type) {
case 'code' :
this.openModal(CodeEditModal, {code: this.props.article, planet: this.props.planet})
@@ -34,6 +35,7 @@ module.exports = React.createClass({
}
},
openDeleteModal: function () {
if (this.props.article == null) return
switch (this.props.article.type) {
case 'code' :
this.openModal(CodeDeleteModal, {code: this.props.article, planet: this.props.planet})
@@ -64,7 +66,7 @@ module.exports = React.createClass({
<div className='detailHeader'>
<div className='itemLeft'>
<ProfileImage className='profileImage' size='25' email={article.User.email}/>
<i className='fa fa-file-text-o fa-fw'></i>
<i className='fa fa-code fa-fw'></i>
</div>
<div className='itemRight'>
@@ -74,14 +76,18 @@ module.exports = React.createClass({
</div>
<span className='itemControl'>
<button onClick={this.openEditModal} className='btn-default btn-square btn-sm'><i className='fa fa-edit fa-fw'></i></button>
<button onClick={this.openDeleteModal} className='btn-default btn-square btn-sm'><i className='fa fa-trash fa-fw'></i></button>
<button id='articleEditButton' onClick={this.openEditModal} className='editButton'>
<i className='fa fa-edit fa-fw'></i>
<div className='tooltip'>Edit</div>
</button>
<button onClick={this.openDeleteModal} className='deleteButton'>
<i className='fa fa-trash fa-fw'></i>
<div className='tooltip'>Delete</div>
</button>
</span>
</div>
<div className='detailBody'>
<div className='content'>
<CodeViewer code={article.content} mode={article.mode}/>
</div>
<CodeViewer className='content' code={article.content} mode={article.mode}/>
</div>
</div>
)
@@ -101,8 +107,14 @@ module.exports = React.createClass({
</div>
<span className='itemControl'>
<button onClick={this.openEditModal} className='btn-default btn-square btn-sm'><i className='fa fa-edit fa-fw'></i></button>
<button onClick={this.openDeleteModal} className='btn-default btn-square btn-sm'><i className='fa fa-trash fa-fw'></i></button>
<button id='articleEditButton' onClick={this.openEditModal} className='editButton'>
<i className='fa fa-edit fa-fw'></i>
<div className='tooltip'>Edit</div>
</button>
<button onClick={this.openDeleteModal} className='deleteButton'>
<i className='fa fa-trash fa-fw'></i>
<div className='tooltip'>Delete</div>
</button>
</span>
</div>
<div className='detailBody'>

View File

@@ -1,6 +1,5 @@
var React = require('react/addons')
var ReactRouter = require('react-router')
var Link = ReactRouter.Link
var moment = require('moment')
var ForceUpdate = require('../Mixins/ForceUpdate')
@@ -16,9 +15,10 @@ module.exports = React.createClass({
},
handleArticleClikck: function (article) {
if (article.type === 'code') {
return function () {
return function (e) {
var params = this.getParams()
document.getElementById('articleEditButton').focus()
this.transitionTo('codes', {
userName: params.userName,
planetName: params.planetName,
@@ -28,9 +28,10 @@ module.exports = React.createClass({
}
if (article.type === 'note') {
return function () {
return function (e) {
var params = this.getParams()
document.getElementById('articleEditButton').focus()
this.transitionTo('notes', {
userName: params.userName,
planetName: params.planetName,
@@ -51,8 +52,6 @@ module.exports = React.createClass({
var params = this.getParams()
var isActive = article.type === 'code' ? this.isActive('codes') && parseInt(params.localId, 10) === article.localId : this.isActive('notes') && parseInt(params.localId, 10) === article.localId
var handleClick
if (article.type === 'code') {
return (
<li onClick={this.handleArticleClikck(article)} key={'code-' + article.id}>
@@ -63,7 +62,7 @@ module.exports = React.createClass({
</div>
<div className='itemRight'>
<div className='itemInfo'>{moment(article.updatedAt).fromNow()} by <span className='userProfileName'>{article.User.profileName}</span></div>
<div className='description'>{article.description.length > 50 ? article.description.substring(0, 50) + ' …' : article.description}</div>
<div className='description'>{article.description}</div>
<div className='tags'><i className='fa fa-tags'/>{tags}</div>
</div>
</div>
@@ -94,7 +93,7 @@ module.exports = React.createClass({
return (
<div className='PlanetArticleList'>
<ul>
<ul ref='articles'>
{articles}
</ul>
</div>

View File

@@ -5,11 +5,12 @@ var React = require('react/addons')
var Hq = require('../Services/Hq')
var LinkedState = require('../Mixins/LinkedState')
var KeyCaster = require('../Mixins/KeyCaster')
var PlanetStore = require('../Stores/PlanetStore')
module.exports = React.createClass({
mixins: [LinkedState],
mixins: [LinkedState, KeyCaster('planetCreateModal')],
propTypes: {
ownerName: React.PropTypes.string,
transitionTo: React.PropTypes.func,
@@ -24,33 +25,57 @@ module.exports = React.createClass({
name: '',
public: true
},
ownerName: ownerName
ownerName: ownerName,
error: null
}
},
componentDidMount: function () {
React.findDOMNode(this.refs.name).focus()
},
onListen: function (res) {
if (res.status === 'planetCreated') {
this.props.close()
onKeyCast: function (e) {
switch (e.status) {
case 'closeModal':
this.props.close()
break
case 'submitPlanetCreateModal':
this.handleSubmit()
break
}
},
handleSubmit: function () {
Hq.createPlanet(this.state.ownerName, this.state.planet)
.then(function (res) {
var planet = res.body
this.setState({error: null}, function () {
Hq.createPlanet(this.state.ownerName, this.state.planet)
.then(function (res) {
var planet = res.body
PlanetStore.Actions.update(planet)
PlanetStore.Actions.update(planet)
if (this.props.transitionTo != null) {
this.props.transitionTo('planetHome', {userName: planet.userName, planetName: planet.name})
}
if (this.props.transitionTo != null) {
this.props.transitionTo('planetHome', {userName: planet.userName, planetName: planet.name})
}
this.props.close()
}.bind(this))
.catch(function (err) {
console.error(err)
})
this.props.close()
}.bind(this))
.catch(function (err) {
console.error(err)
if (err.status == null) return this.setState({error: {message: 'Check your network connection'}})
switch (err.status) {
case 403:
this.setState({error: err.response.body})
break
case 422:
this.setState({error: {message: 'Planet name should be Alphanumeric with _, -'}})
break
case 409:
this.setState({error: {message: 'The entered name already in use'}})
break
default:
this.setState({error: {message: 'Unexpected error occured! please try again'}})
}
}.bind(this))
})
},
render: function () {
var teamOptions = this.state.user.Teams.map(function (team) {
@@ -75,6 +100,8 @@ module.exports = React.createClass({
</select>
</div>
{this.state.error != null ? (<p className='errorAlert'>{this.state.error.message != null ? this.state.error.message : 'Error message undefined'}</p>) : null}
<button onClick={this.handleSubmit} className='submitButton'>
<i className='fa fa-check'/>
</button>

View File

@@ -21,7 +21,22 @@ module.exports = React.createClass({
}
},
componentDidMount: function () {
React.findDOMNode(this.refs.search).focus()
var search = React.findDOMNode(this.refs.search)
search.addEventListener('keydown', this.handleSearchKeyDown)
},
componentWillUnmount: function () {
var search = React.findDOMNode(this.refs.search)
search.removeEventListener('keydown', this.handleSearchKeyDown)
},
handleSearchKeyDown: function (e) {
if (e.keyCode === 38 || e.keyCode === 40) {
var search = React.findDOMNode(this.refs.search)
search.blur()
e.preventDefault()
}
if (e.keyCode !== 27 && (e.keyCode !== 13 || !e.metaKey)) {
e.stopPropagation()
}
},
openPlanetSettingModal: function () {
this.openModal(PlanetSettingModal, {planet: this.props.currentPlanet})
@@ -42,12 +57,13 @@ module.exports = React.createClass({
{this.props.currentPlanet.public ? null : (
<div className='private'>
<i className='fa fa-lock'/>
<div className='privateTooltip'>Private planet</div>
<div className='tooltip'>Private planet</div>
</div>
)}
<button onClick={this.openPlanetSettingModal} className='menuBtn'>
<button onClick={this.openPlanetSettingModal} className='planetSettingButton'>
<i className='fa fa-chevron-down'></i>
<div className='tooltip'>Planet setting</div>
</button>
</div>
<div className='headerControl'>
@@ -55,9 +71,13 @@ module.exports = React.createClass({
<i className='fa fa-search'/>
<input onChange={this.props.onSearchChange} value={this.props.search} ref='search' type='text' className='inline-input circleInput' placeholder='Search...'/>
</div>
<button onClick={this.refresh} className='refreshButton'><i className='fa fa-refresh'/></button>
<button onClick={this.refresh} className='refreshButton'>
<i className='fa fa-refresh'/>
<div className='tooltip'>Refresh planet</div>
</button>
<a onClick={this.openExternal} href='http://b00st.io' className='logo'>
<img width='44' height='44' src='resources/favicon-230x230.png'/>
<div className='tooltip'>Boost official page</div>
</a>
</div>
</div>

View File

@@ -3,29 +3,47 @@ var ReactRouter = require('react-router')
var Navigation = ReactRouter.Navigation
var Modal = require('../Mixins/Modal')
var LaunchModal = require('../Components/LaunchModal')
var PlanetNavigator = React.createClass({
module.exports = React.createClass({
mixins: [Modal, Navigation],
propTypes: {
planet: React.PropTypes.shape({
name: React.PropTypes.string
name: React.PropTypes.string,
Owner: React.PropTypes.shape({
id: React.PropTypes.number,
userType: React.PropTypes.string
})
}),
search: React.PropTypes.string,
toggleCodeFilter: React.PropTypes.func,
toggleNoteFilter: React.PropTypes.func
toggleNoteFilter: React.PropTypes.func,
currentUser: React.PropTypes.shape({
id: React.PropTypes.number,
userType: React.PropTypes.string,
Teams: React.PropTypes.array
})
},
getInitialState: function () {
return {
isLaunchModalOpen: false
}
},
submitLaunchModal: function (ret) {
this.setState({isLaunchModalOpen: false})
},
openLaunchModal: function () {
this.openModal(LaunchModal, {planet: this.props.planet, transitionTo: this.transitionTo})
},
isMyPlanet: function () {
if (this.props.currentUser == null) return false
if (this.props.planet.Owner.userType === 'person' && this.props.planet.Owner.id !== this.props.currentUser.id) return false
if (this.props.planet.Owner.userType === 'team' && !this.props.currentUser.Teams.some(function (team) {
if (team.id === this.props.planet.Owner.id) return true
return false
}.bind(this))) return false
return true
},
render: function () {
var keywords = this.props.search.split(' ')
var usingCodeFilter = keywords.some(function (keyword) {
@@ -39,9 +57,11 @@ var PlanetNavigator = React.createClass({
return (
<div className='PlanetNavigator'>
<button onClick={this.openLaunchModal} className='launchButton btn-primary btn-block'>
<i className='fa fa-rocket fa-fw'/> Launch
</button>
{this.isMyPlanet() ? (
<button onClick={this.openLaunchModal} className='launchButton btn-primary btn-block'>
<i className='fa fa-rocket fa-fw'/> Launch
</button>
) : null}
<nav className='articleFilters'>
<a className={usingCodeFilter && !usingNoteFilter ? 'active' : ''} onClick={this.props.toggleCodeFilter}>
<i className='fa fa-code fa-fw'/> Codes
@@ -54,5 +74,3 @@ var PlanetNavigator = React.createClass({
)
}
})
module.exports = PlanetNavigator

View File

@@ -3,11 +3,12 @@ var React = require('react/addons')
var Hq = require('../Services/Hq')
var LinkedState = require('../Mixins/LinkedState')
var KeyCaster = require('../Mixins/KeyCaster')
var PlanetStore = require('../Stores/PlanetStore')
module.exports = React.createClass({
mixins: [LinkedState],
mixins: [LinkedState, KeyCaster('planetSettingModal')],
propTypes: {
close: React.PropTypes.func,
planet: React.PropTypes.shape({
@@ -35,6 +36,13 @@ module.exports = React.createClass({
deleteConfirmation: ''
}
},
onKeyCast: function (e) {
switch (e.status) {
case 'closeModal':
this.props.close()
break
}
},
activePlanetProfile: function () {
this.setState({currentTab: 'profile'})
},
@@ -50,18 +58,44 @@ module.exports = React.createClass({
handleSavePlanetProfile: function (e) {
var planet = this.props.planet
this.setState({profileSubmitStatus: 'sending'}, function () {
this.setState({profileFormStatus: 'sending', profileFormError: null}, function () {
Hq.updatePlanet(planet.userName, planet.name, this.state.planet)
.then(function (res) {
var planet = res.body
this.setState({profileSubmitStatus: 'done'})
console.log(planet)
this.setState({profileFormStatus: 'done'})
PlanetStore.Actions.update(planet)
this.props.close()
}.bind(this))
.catch(function (err) {
this.setState({profileSubmitStatus: 'error'})
console.error(err)
var newState = {
profileFormStatus: 'error'
}
if (err.status == null) {
newState.profileFormError = {message: 'Check your network connection'}
return this.setState(newState)
}
switch (err.status) {
case 403:
newState.profileFormError = err.response.body
this.setState(newState)
break
case 422:
newState.profileFormError = {message: 'Planet name should be Alphanumeric with _, -'}
this.setState(newState)
break
case 409:
newState.profileFormError = {message: 'The entered name already in use'}
this.setState(newState)
break
default:
newState.profileFormError = {message: 'Undefined error please try again'}
this.setState(newState)
}
}.bind(this))
})
},
@@ -122,11 +156,11 @@ module.exports = React.createClass({
<div className='formConfirm'>
<button onClick={this.handleSavePlanetProfile} className='saveButton btn-primary'>Save</button>
<div className={'alertInfo' + (this.state.profileSubmitStatus === 'sending' ? '' : ' hide')}>on Sending...</div>
<div className={'alertInfo' + (this.state.profileFormStatus === 'sending' ? '' : ' hide')}>on Sending...</div>
<div className={'alertError' + (this.state.profileSubmitStatus === 'error' ? '' : ' hide')}>Connection failed.. Try again.</div>
<div className={'alertError' + (this.state.profileFormStatus === 'error' ? '' : ' hide')}>{this.state.profileFormError != null ? this.state.profileFormError.message : 'Unexpected error occured! please try again'}</div>
<div className={'alertSuccess' + (this.state.profileSubmitStatus === 'done' ? '' : ' hide')}>Successfully done!!</div>
<div className={'alertSuccess' + (this.state.profileFormStatus === 'done' ? '' : ' hide')}>Successfully done!!</div>
</div>
</div>
)

View File

@@ -5,11 +5,12 @@ var React = require('react/addons')
var Hq = require('../Services/Hq')
var LinkedState = require('../Mixins/LinkedState')
var KeyCaster = require('../Mixins/KeyCaster')
var UserStore = require('../Stores/UserStore')
module.exports = React.createClass({
mixins: [LinkedState],
mixins: [LinkedState, KeyCaster('teamCreateModal')],
propTypes: {
user: React.PropTypes.shape({
name: React.PropTypes.string
@@ -21,33 +22,62 @@ module.exports = React.createClass({
return {
team: {
name: ''
}
},
error: null
}
},
componentDidMount: function () {
React.findDOMNode(this.refs.teamName).focus()
},
onKeyCast: function (e) {
switch (e.status) {
case 'closeModal':
this.props.close()
break
case 'submitTeamCreateModal':
this.handleSubmit()
break
}
},
handleSubmit: function () {
Hq.createTeam(this.props.user.name, this.state.team)
.then(function (res) {
var currentUser = JSON.parse(localStorage.getItem('currentUser'))
var team = res.body
this.setState({error: null}, function () {
Hq.createTeam(this.props.user.name, this.state.team)
.then(function (res) {
var currentUser = JSON.parse(localStorage.getItem('currentUser'))
var team = res.body
currentUser.Teams.push(team)
localStorage.setItem('currentUser', JSON.stringify(currentUser))
UserStore.Actions.update(currentUser)
currentUser.Teams.push(team)
localStorage.setItem('currentUser', JSON.stringify(currentUser))
UserStore.Actions.update(currentUser)
if (this.props.transitionTo != null) {
this.props.transitionTo('userHome', {userName: team.name})
}
this.props.close()
}.bind(this))
.catch(function (err) {
console.error(err)
})
if (this.props.transitionTo != null) {
this.props.transitionTo('userHome', {userName: team.name})
}
this.props.close()
}.bind(this))
.catch(function (err) {
console.error(err)
if (err.status == null) return this.setState({error: {message: 'Check your network connection'}})
switch (err.status) {
case 422:
this.setState({error: {message: 'Team name should be Alphanumeric with _, -'}})
break
case 409:
this.setState({error: {message: 'The entered name already in use'}})
break
default:
this.setState({error: {message: 'Error message undefined'}})
}
}.bind(this))
})
},
render: function () {
return (
<div className='TeamCreateModal modal'>
<input valueLink={this.linkState('team.name')} className='nameInput stripInput' placeholder='Create new team'/>
<input ref='teamName' valueLink={this.linkState('team.name')} className='nameInput stripInput' placeholder='Create new team'/>
{this.state.error != null ? (<p className='errorAlert'>{this.state.error.message != null ? this.state.error.message : 'Unintended error occured'}</p>) : null}
<button onClick={this.handleSubmit} className='submitButton'>
<i className='fa fa-check'/>
</button>

View File

@@ -8,6 +8,7 @@ var Hq = require('../Services/Hq')
var LinkedState = require('../Mixins/LinkedState')
var Helper = require('../Mixins/Helper')
var KeyCaster = require('../Mixins/KeyCaster')
var UserStore = require('../Stores/UserStore')
@@ -30,7 +31,7 @@ var getOptions = function (input, callback) {
}
module.exports = React.createClass({
mixins: [LinkedState, Reflux.listenTo(UserStore, 'onUserChange'), Helper],
mixins: [LinkedState, Reflux.listenTo(UserStore, 'onUserChange'), Helper, KeyCaster('teamSettingsModal')],
propTypes: {
team: React.PropTypes.shape({
id: React.PropTypes.number,
@@ -38,7 +39,8 @@ module.exports = React.createClass({
profileName: React.PropTypes.string,
email: React.PropTypes.string,
Members: React.PropTypes.array
})
}),
close: React.PropTypes.func
},
getInitialState: function () {
var team = this.props.team
@@ -55,6 +57,13 @@ module.exports = React.createClass({
updatingMember: false
}
},
onKeyCast: function (e) {
switch (e.status) {
case 'closeModal':
this.props.close()
break
}
},
onUserChange: function (res) {
var member
switch (res.status) {

View File

@@ -7,21 +7,33 @@ var State = ReactRouter.State
var Navigation = ReactRouter.Navigation
var AuthFilter = require('../Mixins/AuthFilter')
var KeyCaster = require('../Mixins/KeyCaster')
var HomeNavigator = require('../Components/HomeNavigator')
module.exports = React.createClass({
mixins: [AuthFilter.OnlyUser, State, Navigation],
mixins: [AuthFilter.OnlyUser, State, Navigation, KeyCaster('homeContainer')],
componentDidMount: function () {
if (this.isActive('homeEmpty')) {
var user = JSON.parse(localStorage.getItem('currentUser'))
if (user.Planets != null && user.Planets.length > 0) {
this.transitionTo('planet', {userName: user.name, planetName: user.Planets[0].name})
return
}
this.transitionTo('userHome', {userName: user.name})
}
},
onKeyCast: function (e) {
switch (e.status) {
case 'switchPlanet':
this.refs.navigator.switchPlanetByIndex(e.data)
break
}
},
render: function () {
return (
<div className='HomeContainer'>
<HomeNavigator/>
<HomeNavigator ref='navigator'/>
<RouteHandler/>
</div>
)

View File

@@ -96,7 +96,10 @@ module.exports = React.createClass({
{this.state.updateAvailable ? (
<button onClick={this.updateApp} className='appUpdateButton'><i className='fa fa-cloud-download'/> Update available!</button>
) : null}
<button onClick={this.openContactModal} className='contactButton'><i className='fa fa-paper-plane-o'/></button>
<button onClick={this.openContactModal} className='contactButton'>
<i className='fa fa-paper-plane-o'/>
<div className='tooltip'>Contact us</div>
</button>
<RouteHandler/>
</div>
)

View File

@@ -14,12 +14,13 @@ var Hq = require('../Services/Hq')
var Modal = require('../Mixins/Modal')
var ArticleFilter = require('../Mixins/ArticleFilter')
var Helper = require('../Mixins/Helper')
var KeyCaster = require('../Mixins/KeyCaster')
var UserStore = require('../Stores/UserStore')
var PlanetStore = require('../Stores/PlanetStore')
module.exports = React.createClass({
mixins: [ReactRouter.Navigation, ReactRouter.State, Modal, Reflux.listenTo(UserStore, 'onUserChange'), Reflux.listenTo(PlanetStore, 'onPlanetChange'), ArticleFilter, Helper],
mixins: [ReactRouter.Navigation, ReactRouter.State, Modal, Reflux.listenTo(UserStore, 'onUserChange'), Reflux.listenTo(PlanetStore, 'onPlanetChange'), ArticleFilter, Helper, KeyCaster('planetContainer')],
propTypes: {
params: React.PropTypes.object,
planetName: React.PropTypes.string
@@ -62,6 +63,28 @@ module.exports = React.createClass({
})
}
},
onKeyCast: function (e) {
switch (e.status) {
case 'openLaunchModal':
this.refs.navigator.openLaunchModal()
break
case 'selectNextArticle':
this.selectNextArticle()
break
case 'selectPriorArticle':
this.selectPriorArticle()
break
case 'toggleFocusSearchInput':
this.toggleFocusSearchInput()
break
case 'openEditModal':
this.refs.detail.openEditModal()
break
case 'openDeleteModal':
this.refs.detail.openDeleteModal()
break
}
},
onPlanetChange: function (res) {
if (this.state.planet == null) return
@@ -207,6 +230,18 @@ module.exports = React.createClass({
return
}
var listElement = this.refs.list.refs.articles.getDOMNode()
var articleElement = listElement.querySelectorAll('li')[index]
var overflowBelow = listElement.clientHeight + listElement.scrollTop < articleElement.offsetTop + articleElement.clientHeight
if (overflowBelow) {
listElement.scrollTop = articleElement.offsetTop + articleElement.clientHeight - listElement.clientHeight
}
var overflowAbove = listElement.scrollTop > articleElement.offsetTop
if (overflowAbove) {
listElement.scrollTop = articleElement.offsetTop
}
if (article.type === 'code') {
params.localId = article.localId
this.transitionTo('codes', params)
@@ -237,9 +272,17 @@ module.exports = React.createClass({
if (index > 0) {
this.selectArticleByListIndex(index - 1)
} else {
React.findDOMNode(this).querySelector('.PlanetHeader .searchInput input').focus()
React.findDOMNode(this.refs.header.refs.search).focus()
}
},
toggleFocusSearchInput: function () {
var search = React.findDOMNode(this.refs.header.refs.search)
if (document.activeElement === search) {
React.findDOMNode(this.refs.header.refs.search).blur()
return
}
React.findDOMNode(this.refs.header.refs.search).focus()
},
handleSearchChange: function (e) {
this.setState({search: e.target.value}, function () {
this.selectArticleByListIndex(0)
@@ -309,9 +352,6 @@ module.exports = React.createClass({
this.setState({search: '#' + tag})
}.bind(this)
},
focus: function () {
React.findDOMNode(this).focus()
},
render: function () {
if (this.state.planet == null) return (<div/>)
@@ -346,6 +386,7 @@ module.exports = React.createClass({
return (
<div className='PlanetContainer'>
<PlanetHeader
ref='header'
search={this.state.search}
fetchPlanet={this.fetchPlanet}
onSearchChange={this.handleSearchChange}
@@ -358,7 +399,8 @@ module.exports = React.createClass({
showAll={this.showAll}
toggleCodeFilter={this.toggleCodeFilter}
toggleNoteFilter={this.toggleNoteFilter}
planet={this.state.planet}/>
planet={this.state.planet}
currentUser={this.state.currentUser}/>
<PlanetArticleList showOnlyWithTag={this.applyTagFilter} ref='list' articles={filteredArticles}/>

View File

@@ -6,10 +6,11 @@ var Link = ReactRouter.Link
var AuthFilter = require('../Mixins/AuthFilter')
var LinkedState = require('../Mixins/LinkedState')
var ExternalLink = require('../Mixins/ExternalLink')
var Hq = require('../Services/Hq')
module.exports = React.createClass({
mixins: [LinkedState, ReactRouter.Navigation, AuthFilter.OnlyGuest],
mixins: [LinkedState, ReactRouter.Navigation, AuthFilter.OnlyGuest, ExternalLink],
getInitialState: function () {
return {
user: {},
@@ -129,7 +130,7 @@ module.exports = React.createClass({
</div>
</form>
<p className='alert'>会員登録することで当サイトの利用規約及びCookieの使用を含むデータに関するポリシーに同意するものとします</p>
<p className='alert'>会員登録することで<a onClick={this.openExternal} href='http://boostio.github.io/regulations.html'>当サイトの利用規約</a>及び<a onClick={this.openExternal} href='http://boostio.github.io/privacypolicies.html'>Cookieの使用を含むデータに関するポリシー</a>に同意するものとします</p>
</div>
)
}

View File

@@ -190,7 +190,6 @@ module.exports = React.createClass({
return this.renderUserHome(currentUser)
}
} else if (this.isActive('planet') && user != null && user.userType === 'team') {
console.log(user.Members)
var members = user.Members.map(function (member) {
return (
<li key={'user-' + member.id}><Link to='userHome' params={{userName: member.name}}>
@@ -224,7 +223,9 @@ module.exports = React.createClass({
renderTeamHome: function (currentUser) {
var user = this.state.user
var isOwner = true
var isOwner = user.Members == null ? false : user.Members.some(function (member) {
return member.id === currentUser.id && member.TeamMember.role === 'owner'
})
var userPlanets = user.Planets.map(function (planet) {
return (
@@ -258,7 +259,7 @@ module.exports = React.createClass({
<div className='userName'>{user.name}</div>
</div>
<button onClick={this.openTeamSettingsModal} className='editProfileButton'>Team settings</button>
{isOwner ? (<button onClick={this.openTeamSettingsModal} className='editProfileButton'>Team settings</button>) : null}
</div>
<div className='memberList'>
<div className='memberLabel'>{members.length} {members.length > 1 ? 'Members' : 'Member'}</div>
@@ -317,7 +318,7 @@ module.exports = React.createClass({
})
return (
<div key={'user-' + team.id} className='planetGroup'>
<div className='planetGroupLabel'>{team.name}</div>
<div className='planetGroupLabel'>{team.profileName} <small>@{team.name}</small></div>
<ul className='planets'>
{planets}
{isOwner ? (<li><button onClick={this.openPlanetCreateModalWithOwnerName(team.name)} className='createPlanetButton'><i className='fa fa-plus-square-o'/> Create new planet</button></li>) : null}
@@ -352,7 +353,7 @@ module.exports = React.createClass({
<div className='planetList'>
<div className='planetLabel'>{planetCount} {planetCount > 1 ? 'Planets' : 'Planet'}</div>
<div className='planetGroup'>
<div className='planetGroupLabel'>{user.profileName}</div>
<div className='planetGroupLabel'>{user.profileName} <small>@{user.name}</small></div>
<ul className='planets'>
{userPlanets}
{isOwner ? (<li><button onClick={this.openPlanetCreateModalWithOwnerName(user.name)} className='createPlanetButton'><i className='fa fa-plus-square-o'/> Create new planet</button></li>) : null}

View File

@@ -1,4 +1,5 @@
function deleteItemFromTargetArray (item, targetArray) {
if (targetArray == null) targetArray = []
targetArray.some(function (_item, index) {
if (_item.id === item.id) {
targetArray.splice(index, 1)
@@ -11,6 +12,8 @@ function deleteItemFromTargetArray (item, targetArray) {
}
function updateItemToTargetArray (item, targetArray) {
if (targetArray == null) targetArray = []
var isNew = !targetArray.some(function (_item, index) {
if (_item.id === item.id) {
targetArray.splice(index, 1, item)

View File

@@ -0,0 +1,100 @@
var Reflux = require('reflux')
var state = {
}
var keyDown = Reflux.createAction()
var KeyStore = Reflux.createStore({
init: function () {
this.listenTo(keyDown, this.onKeyDown)
document.addEventListener('keydown', function (e) {
keyDown(e)
})
},
setState: function (newState, cb) {
for (var key in newState) {
state[key] = newState[key]
}
if (typeof cb === 'function') cb()
},
onKeyDown: function (e) {
/*
Modals
*/
if (state.codeForm || state.noteForm || state.noteDeleteModal || state.codeDeleteModal || state.addMemberModal || state.aboutModal || state.editProfileModal || state.contactModal || state.teamCreateModal || state.planetCreateModal || state.planetSettingModal || state.teamSettingsModal || state.logoutModal) {
// ESC
if (e.keyCode === 27) this.cast('closeModal')
// Cmd + Enter
if (e.keyCode === 13 && e.metaKey) {
if (state.codeForm) this.cast('submitCodeForm')
if (state.noteForm) this.cast('submitNoteForm')
if (state.codeDeleteModal) this.cast('submitCodeDeleteModal')
if (state.noteDeleteModal) this.cast('submitNoteDeleteModal')
if (state.addMemberModal) this.cast('submitAddMemberModal')
if (state.contactModal) this.cast('submitContactModal')
if (state.teamCreateModal) this.cast('submitTeamCreateModal')
if (state.planetCreateModal) this.cast('submitPlanetCreateModal')
if (state.logoutModal) this.cast('submitLogoutModal')
}
return
}
/*
PlanetContainer
*/
if (state.planetContainer) {
// Cmd + Enter, A
if ((e.keyCode === 13 && e.metaKey) || e.keyCode === 65) this.cast('openLaunchModal')
// Esc
if (e.keyCode === 27) this.cast('toggleFocusSearchInput')
// Up
if (e.keyCode === 38) this.cast('selectPriorArticle')
// Down
if (e.keyCode === 40) this.cast('selectNextArticle')
// E
if (e.keyCode === 69) this.cast('openEditModal')
// D
if (e.keyCode === 68) this.cast('openDeleteModal')
}
/*
HomeContainer
*/
if (state.homeContainer) {
if (e.keyCode > 48 && e.keyCode < 58 && e.metaKey) {
this.cast('switchPlanet', e.keyCode - 48)
}
}
},
cast: function (status, data) {
this.trigger({
status: status,
data: data
})
}
})
module.exports = function (stateKey) {
return {
mixins: [Reflux.listenTo(KeyStore, 'onKeyCast')],
componentDidMount: function () {
var newState = {}
newState[stateKey] = true
KeyStore.setState(newState)
},
componentWillUnmount: function () {
var newState = {}
newState[stateKey] = false
KeyStore.setState(newState)
}
}
}

View File

@@ -35,6 +35,9 @@ module.exports = {
fetchUser: function (userName) {
return request
.get(apiUrl + 'resources/' + userName)
.set({
Authorization: 'Bearer ' + localStorage.getItem('token')
})
},
updateUser: function (userName, input) {
return request
@@ -79,6 +82,9 @@ module.exports = {
fetchPlanet: function (userName, planetName) {
return request
.get(apiUrl + 'resources/' + userName + '/planets/' + planetName)
.set({
Authorization: 'Bearer ' + localStorage.getItem('token')
})
},
updatePlanet: function (userName, planetName, input) {
return request

View File

@@ -53,6 +53,14 @@ module.exports = Reflux.createStore({
localStorage.setItem('currentUser', JSON.stringify(currentUser))
UserStore.Actions.update(currentUser)
planet.Codes.forEach(function (code) {
code.type = 'code'
})
planet.Notes.forEach(function (note) {
note.type = 'note'
})
// Update the planet
localStorage.setItem('planet-' + planet.id, JSON.stringify(planet))

View File

@@ -1,16 +1,55 @@
<!DOCTYPE html>
<html>
<head>
<script>
var version = require('remote').getGlobal('version')
document.title = 'Boost ' + ((version == null || version.length === 0) ? 'DEV version' : 'v' + version)
</script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css" media="screen" title="no title" charset="utf-8">
<link rel="shortcut icon" href="favicon.ico">
<style>
@font-face {
font-family: 'Lato';
src: url('../../Lato-Regular.woff2') format('woff2'), /* Modern Browsers */
url('../../Lato-Regular.woff') format('woff'), /* Modern Browsers */
url('../../Lato-Regular.ttf') format('truetype');
font-style: normal;
font-weight: normal;
text-rendering: optimizeLegibility;
}
#loadingCover{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
box-sizing: border-box;
padding: 65px 0;
font-family: sans-serif;
}
#loadingCover img{
display: block;
margin: 75px auto 5px;
width: 160px;
height: 160px;
}
#loadingCover .message{
font-size: 30px;
text-align: center;
line-height: 1.6;
font-weight: 100;
color: #888;
}
</style>
</head>
<body>
<div id="loadingCover">
<img src="resources/favicon-230x230.png">
<div class='message'>Loading...</div>
</div>
<div id="content"></div>
<script>
if (!Object.assign) {
Object.defineProperty(Object, 'assign', {
@@ -45,13 +84,13 @@
});
}
require('electron-stylus')(__dirname + '/../styles/main/index.styl')
</script>
</head>
<body>
<div id="content"></div>
<script src="../ace/src-min/ace.js"></script>
<script>
var version = require('remote').getGlobal('version')
document.title = 'Boost ' + ((version == null || version.length === 0) ? 'DEV version' : 'v' + version)
require('../electron-stylus')(__dirname + '/../styles/main/index.styl', 'mainCss')
require('node-jsx').install({ harmony: true, extension: '.jsx' })
require('./index.jsx')
</script>

View File

@@ -34,7 +34,13 @@ var routes = (
</Route>
</Route>
)
var loadingCover = document.getElementById('loadingCover')
ReactRouter.run(routes, ReactRouter.HashLocation, function (Root) {
React.render(<Root/>, document.getElementById('content'))
if (loadingCover != null) {
loadingCover.parentNode.removeChild(loadingCover)
loadingCover = null
}
})

View File

@@ -46,6 +46,9 @@ body
border solid 2px transparent
box-sizing border-box
cursor pointer
white-space nowrap
overflow-x hidden
text-overflow ellipsis
.divider
box-sizing border-box
border-bottom solid 1px borderColor

View File

@@ -64,40 +64,35 @@ articleListWidth= 275px
color inactiveColor
&:hover
color textColor
.privateTooltip
position fixed
z-index popupZIndex
background-color transparentify(invBackgroundColor, 80%)
color invTextColor
padding 10px
font-size 0.9em
line-height 0.9em
border-radius 5px
white-space nowrap
opacity 0
transition 0.1s
pointer-events none
.tooltip
tooltip()
margin-left -30px
&:hover .privateTooltip
&:hover .tooltip
opacity 1
.menuBtn
.planetSettingButton
position absolute
top 12px
top 15px
right 5px
font-size 1em
font-size 0.8em
btnDefault()
box-sizing border-box
circle()
width 33px
height 33px
width 26px
height 26px
text-align center
cursor pointer
transition 0.1s
transform scale(0.8)
&:focus, &.focus
outline none
.tooltip
tooltip()
margin-top 11px
margin-left -36px
&:hover .tooltip
opacity 1
.headerControl
noSelect()
absolute top bottom right
@@ -118,10 +113,11 @@ articleListWidth= 275px
.refreshButton
display block
position absolute
top 12px
top 15px
right 55px
width 28px
height 28px
width 26px
height 26px
font-size 0.8em
btnDefault()
circle()
text-align center
@@ -129,16 +125,28 @@ articleListWidth= 275px
transition 0.1s
&:focus, &.focus
outline none
.tooltip
tooltip()
margin-top 11px
margin-left -39px
&:hover .tooltip
opacity 1
.logo
display block
position absolute
top 4px
right 10px
cursor pointer
transition 0.1s
opacity 0.9
&:hover, &.hover
img
transition 0.1s
opacity 0.9
&:hover img, &:hover .tooltip
opacity 1
.tooltip
tooltip()
margin-top -5px
margin-left -67px
.PlanetNavigator
absolute bottom left
@@ -178,6 +186,7 @@ articleListWidth= 275px
overflow-y auto
li
.articleItem
noSelect()
border solid 2px transparent
position relative
height 94px
@@ -283,23 +292,41 @@ articleListWidth= 275px
z-index 1
top 2px
right 2px
.deleteButton, .editButton
btnDefault()
text-align center
width 33px
height 33px
border-radius 16.5px
font-size 15px
margin 0 3px
.tooltip
tooltip()
margin-top 10px
&:hover .tooltip
opacity 1
.editButton .tooltip
margin-left -12px
.deleteButton .tooltip
margin-left -26px
.detailBody
absolute left right bottom
top 105px
.content
position absolute
top 5px
bottom 5px
left 2px
right 2px
box-sizing border-box
padding 5px
border-top solid 1px borderColor
overflow-x hidden
overflow-y auto
&.noteDetail
.detailBody .content
overflow-x hidden
overflow-y auto
marked()
&.codeDetail
.detailBody .content
.ace_editor
position absolute
top 5px
bottom 5px
left 2px
right 2px
absolute left right top bottom

View File

@@ -1,5 +1,6 @@
.HomeContainer
.HomeNavigator
noSelect()
background-color planetNavBgColor
absolute left top bottom
width 55px
@@ -159,22 +160,11 @@
border-color darken(brandBorderColor, 10%)
background-color brandColor
color white
.newPlanetTooltip
position fixed
z-index 500
background-color transparentify(invBackgroundColor, 80%)
color invTextColor
padding 10px
line-height 1em
border-radius 5px
margin-top -23px
.tooltip
tooltip()
margin-top -22px
margin-left 33px
white-space nowrap
font-size 1.1em
opacity 0
transition 0.1s
pointer-events none
&:hover .newPlanetTooltip
&:hover .tooltip
opacity 1
.UserContainer
absolute top bottom right
@@ -304,6 +294,9 @@
.planetGroupLabel
font-size 1.1em
margin-bottom 15px
small
font-size 0.8em
color inactiveTextColor
.planets
margin-left 15px
li

View File

@@ -7,15 +7,17 @@ global-reset()
@import './containers/*'
html, body
width 100%
height 100%
overflow hidden
width 100%
height 100%
overflow hidden
body
font-family "Lato"
color textColor
font-size fontSize
font-weight 400
button
font-family "Lato"
div, span, a, button, input, textarea
box-sizing border-box
@@ -118,3 +120,9 @@ textarea.block-input
padding 10px 15px
border-radius 5px
background-color backgroundColor
.tooltip
tooltip()
margin-top -22px
margin-left -97px
&:hover .tooltip
opacity 1

View File

@@ -22,10 +22,11 @@ marked()
font-size 0.67em
margin 2.33em auto
h1, h2, h3, h4, h5, h6
font-weight font-weight 400
line-height 1.2em
font-weight 400
line-height 1.4em
p
line-height 1.2em
line-height 1.4em
margin-bottom 15px
img
max-width 100%
strong
@@ -36,14 +37,14 @@ marked()
text-decoration line-through
blockquote
border-left solid 4px brandBorderColor
margin 1em 0
margin 15px 0 15px
padding 0 25px
ul
list-style-type disc
padding-left 35px
li
display list-item
margin 0.5em 0
margin 15px 0
&>li>ul
list-style-type circle
&>li>ul
@@ -53,33 +54,38 @@ marked()
padding-left 35px
li
display list-item
margin 0.5em 0
margin 15px 0
code
font-family monospace
padding 2px 4px
border solid 1px borderColor
border-radius 4px
font-size 0.9em
color black
text-decoration none
background-color #F6F6F6
pre
padding 5px
border solid 1px borderColor
border-radius 5px
margin-bottom 0.5em
overflow-x auto
margin-bottom 15px
background-color #F6F6F6
&>code
padding 0
border none
border-radius 0
color black
table
width 100%
margin 15px 0
margin 15px 0 25px
thead
tr
background-color tableHeadBgColor
th
border-style: solid;
padding: 5px;
border-width: 1px 0 2px 1px;
border-style solid
padding 15px 5px
border-width 1px 0 2px 1px
border-color borderColor
&:last-child
border-right solid 1px borderColor
@@ -89,9 +95,9 @@ marked()
tr:nth-child(2n)
background-color tableEvenBgColor
td
border-style: solid;
padding: 5px;
border-width: 0 0 1px 1px;
border-style solid
padding 15px 5px
border-width 0 0 1px 1px
border-color borderColor
&:last-child
border-right solid 1px borderColor

View File

@@ -0,0 +1,13 @@
tooltip()
position fixed
z-index popupZIndex
background-color transparentify(invBackgroundColor, 80%)
color invTextColor
padding 10px
font-size 12px
line-height 12px
border-radius 5px
white-space nowrap
opacity 0
transition 0.1s
pointer-events none

View File

@@ -97,7 +97,7 @@
float right
padding 12px 10px
border-radius 5px
width 200px
width 320px
font-size 1em
overflow-x hidden
white-space nowrap
@@ -139,7 +139,7 @@
float right
padding 12px 10px
border-radius 5px
width 200px
width 320px
font-size 1em
overflow-x hidden
white-space nowrap
@@ -196,7 +196,6 @@
border-radius 5px
float left
.LaunchModal
.modal-tab
text-align center
@@ -314,6 +313,14 @@
height 55px
circle()
btnPrimary()
.errorAlert
alertError()
padding 12px 10px
border-radius 5px
text-align center
display block
width 360px
margin 0 auto 15px
.ContactModal
padding 15px
@@ -341,6 +348,7 @@
padding 0 15px
border-radius 5px
margin-left 5px
font-size 1em
button.sendButton
btnPrimary()
.confirmation

View File

@@ -1,4 +1,4 @@
module.exports = {
apiUrl: 'http://codexen-server-dev2.elasticbeanstalk.com/'
apiUrl: 'https://api.b00st.io/'
// apiUrl: 'http://localhost:8000/'
}

26
main.js
View File

@@ -27,6 +27,7 @@ var path = require('path')
autoUpdater
.on('error', function (err, message) {
console.error(message)
nn.notify({
title: 'Error! ' + versionText,
icon: path.join(__dirname, 'browser/main/resources/favicon-230x230.png'),
@@ -34,11 +35,7 @@ autoUpdater
})
})
.on('checking-for-update', function () {
nn.notify({
title: 'Boost launched!! ' + versionText,
icon: path.join(__dirname, 'browser/main/resources/favicon-230x230.png'),
message: 'Checking update is available....'
})
// Connecting
})
.on('update-available', function () {
nn.notify({
@@ -85,7 +82,7 @@ app.on('ready', function () {
Menu.setApplicationMenu(menu)
// menu end
appIcon = new Tray(__dirname + '/tray-icon.png')
appIcon.setToolTip('Codexen')
appIcon.setToolTip('Boost')
var trayMenu = new Menu()
trayMenu.append(new MenuItem({
@@ -131,9 +128,10 @@ app.on('ready', function () {
'zoom-factor': 1.0,
'always-on-top': true,
'web-preferences': {
'overlay-scrollbars': true,
'skip-taskbar': true
}
'overlay-scrollbars': true,
'skip-taskbar': true
},
'standard-window': false
})
popUpWindow.loadUrl('file://' + __dirname + '/browser/finder/index.electron.html')
@@ -141,6 +139,7 @@ app.on('ready', function () {
popUpWindow.on('blur', function () {
popUpWindow.hide()
})
popUpWindow.setVisibleOnAllWorkspaces(true)
var globalShortcut = require('global-shortcut')
@@ -167,8 +166,9 @@ function makeNewMainWindow () {
height: 720,
'zoom-factor': 1.0,
'web-preferences': {
'overlay-scrollbars': true
}
'overlay-scrollbars': true
},
'standard-window': false
})
if (update != null) {
mainWindow.webContents.on('did-finish-load', function () {
@@ -178,6 +178,10 @@ function makeNewMainWindow () {
mainWindow.loadUrl('file://' + __dirname + '/browser/main/index.electron.html')
mainWindow.webContents.on('new-window', function (e) {
e.preventDefault()
})
mainWindow.on('closed', function () {
console.log('main closed')
mainWindow = null

View File

@@ -5,7 +5,7 @@ module.exports = [
label: 'Electron',
submenu: [
{
label: 'About Electron',
label: 'About Boost',
selector: 'orderFrontStandardAboutPanel:'
},
{
@@ -89,13 +89,13 @@ module.exports = [
click: function () {
BrowserWindow.getFocusedWindow().reload()
}
},
{
label: 'Toggle DevTools',
accelerator: 'Alt+Command+I',
click: function () {
BrowserWindow.getFocusedWindow().toggleDevTools()
}
// },
// {
// label: 'Toggle DevTools',
// accelerator: 'Alt+Command+I',
// click: function () {
// BrowserWindow.getFocusedWindow().toggleDevTools()
// }
}
]
},

View File

@@ -1,6 +1,6 @@
{
"name": "boost",
"version": "0.2.2",
"version": "0.2.9",
"description": "Boost App",
"main": "main.js",
"scripts": {
@@ -31,7 +31,6 @@
},
"homepage": "https://github.com/Rokt33r/codexen-app#readme",
"dependencies": {
"electron-stylus": "^0.1.0",
"font-awesome": "^4.3.0",
"markdown-it": "^4.3.1",
"md5": "^2.0.0",
@@ -43,6 +42,7 @@
"react-router": "^0.13.3",
"react-select": "^0.5.4",
"reflux": "^0.2.8",
"stylus": "^0.52.0",
"superagent": "^1.2.0",
"superagent-promise": "^1.0.3"
},

View File

@@ -1,5 +0,0 @@
/* global angular */
angular.module('codexen')
.controller('AppController', function ($scope) {
})

View File

@@ -1,34 +0,0 @@
/* global angular */
angular.module('codexen')
.controller('SideNavController', function ($auth, User, $rootScope, $scope, Modal) {
var vm = this
vm.isAuthenticated = $auth.isAuthenticated()
vm.showPP = Modal.showPP
vm.showRegulation = Modal.showRegulation
var reloadUser = function () {
if (vm.isAuthenticated) {
User.me().success(function (data) {
console.log('currentUser', data)
vm.currentUser = data
})
}
}
reloadUser()
vm.signOut = function () {
Modal.signOut()
}
$scope.$on('userSignIn', function () {
vm.isAuthenticated = true
reloadUser()
})
$scope.$on('userSignOut', function () {
vm.isAuthenticated = false
vm.currentUser = null
})
})

View File

@@ -1,17 +0,0 @@
/* global angular */
angular.module('codexen')
.controller('AgreementModalController', function ($modalInstance, Modal) {
var vm = this
vm.isAgreement = true
vm.showPP = Modal.showPP
vm.submit = function () {
$modalInstance.close()
}
vm.cancel = function () {
$modalInstance.dismiss('cancel')
}
})

View File

@@ -1,13 +0,0 @@
/* global angular */
angular.module('codexen')
.controller('PPModalController', function ($modalInstance, Modal) {
var vm = this
vm.isAgreement = false
vm.showPP = Modal.showPP
vm.cancel = function () {
$modalInstance.dismiss('cancel')
}
})

View File

@@ -1,23 +0,0 @@
/* global angular */
angular.module('codexen')
.controller('AuthRegisterController', function ($auth, $log, $state, $rootScope, Modal) {
var vm = this
vm.isEmpty = function (obj) {
for (var i in obj) if (obj.hasOwnProperty(i)) return false
return true
}
vm.signup = function () {
Modal.showAgreement()
.then(function () {
$auth.signup({
email: vm.email,
password: vm.password,
name: vm.name,
profileName: vm.profileName
}).then(function (data) {
$rootScope.$broadcast('userSignIn')
$state.go('home')
})
})
}
})

View File

@@ -1,92 +0,0 @@
<!DOCTYPE html>
<html ng-app="codexen">
<head>
<title>
CodeXen App
</title>
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<meta name="description" content="CodeXen - Short code storage service">
<title>Codexen!</title>
<link rel="stylesheet" href="../vendor/css/font-awesome.css" media="screen" title="no title" charset="utf-8">
<!-- inject:css -->
<link rel="stylesheet" href="styles/app.css">
<link rel="stylesheet" href="../shared/styles/bootstrap.css">
<!-- endinject -->
</head>
<body ng-controller="AppController as app">
<div side-nav id="side-view"></div>
<div ui-view name="main-view" id="main-view"></div>
<script src="../vendor/ace.js"></script>
<script src="../vendor/angular.js"></script>
<script src="../vendor/angular-sanitize.js"></script>
<script src="../vendor/angular-ui-router.js"></script>
<script src="../vendor/ui-bootstrap-tpls.js"></script>
<script src="../vendor/select.js"></script>
<script src="../vendor/satellizer.js"></script>
<script src="../vendor/angular-md5.js"></script>
<script src="../vendor/moment.js"></script>
<script src="../vendor/marked.js"></script>
<script src="../vendor/hotkeys.js" charset="utf-8"></script>
<!-- inject:js -->
<script src="app.js"></script>
<script src="config/states.js"></script>
<script src="controllers/AppController.js"></script>
<script src="directives/btn-delete-recipe.js"></script>
<script src="directives/btn-delete-snippet.js"></script>
<script src="directives/btn-edit-recipe.js"></script>
<script src="directives/btn-edit-snippet.js"></script>
<script src="directives/btn-expand-recipe.js"></script>
<script src="directives/btn-new-recipe.js"></script>
<script src="directives/btn-new-snippet.js"></script>
<script src="directives/recipe-item.js"></script>
<script src="directives/side-nav.js"></script>
<script src="directives/snippet-item.js"></script>
<script src="directives/tag-item.js"></script>
<script src="directives/tag-list.js"></script>
<script src="filters/from-now.js"></script>
<script src="filters/marked.js"></script>
<script src="filters/search-snippets.js"></script>
<script src="services/Modal.js"></script>
<script src="services/Recipe.js"></script>
<script src="services/Settings.js"></script>
<script src="services/Tag.js"></script>
<script src="services/User.js"></script>
<script src="controllers/directives/SideNavController.js"></script>
<script src="controllers/states/AuthRegisterController.js"></script>
<script src="controllers/states/AuthSignInController.js"></script>
<script src="controllers/states/HomeController.js"></script>
<script src="controllers/states/RecipesDetailController.js"></script>
<script src="controllers/states/RecipesListController.js"></script>
<script src="controllers/states/SettingsController.js"></script>
<script src="controllers/states/SnippetsDetailController.js"></script>
<script src="controllers/states/SnippetsListController.js"></script>
<script src="controllers/modals/AgreementModalController.js"></script>
<script src="controllers/modals/DeleteRecipeModalController.js"></script>
<script src="controllers/modals/DeleteSnippetModalController.js"></script>
<script src="controllers/modals/EditRecipeModalController.js"></script>
<script src="controllers/modals/EditSnippetModalController.js"></script>
<script src="controllers/modals/ExpandRecipeModalController.js"></script>
<script src="controllers/modals/NewRecipeModalController.js"></script>
<script src="controllers/modals/NewSnippetModalController.js"></script>
<script src="controllers/modals/PPModalController.js"></script>
<script src="controllers/modals/SelectSnippetModalController.js"></script>
<script src="controllers/modals/SignOutModalController.js"></script>
<script src="../shared/shared.js"></script>
<script src="../shared/directives/ui-ace.js"></script>
<script src="../shared/config/ace.js"></script>
<script src="../shared/config/env.js"></script>
<script src="../shared/config/satellizer.js"></script>
<script src="../shared/services/Snippet.js"></script>
<!-- endinject -->
</body>
</html>

View File

@@ -1,148 +0,0 @@
/* global angular */
angular.module('codexen')
.factory('Modal', function ($modal, $rootScope, $auth) {
var showAgreement = function () {
return $modal.open({
templateUrl: 'tpls/modals/regulation.html',
controller: 'AgreementModalController as vm'
}).result
}
var showRegulation = function () {
return $modal.open({
templateUrl: 'tpls/modals/regulation.html',
controller: 'PPModalController as vm'
})
}
var showPP = function () {
return $modal.open({
templateUrl: 'tpls/modals/pp.html',
controller: 'PPModalController as vm'
})
}
var signOut = function () {
return $modal.open({
templateUrl: 'tpls/modals/sign-out-modal.html',
controller: 'SignOutModalController as vm'
}).result.then(function () {
$auth.logout()
.then(function () {
console.log('Sign Out')
$rootScope.$broadcast('userSignOut')
})
})
}
/* Recipe */
var newRecipe = function () {
return $modal.open({
templateUrl: 'tpls/modals/new-recipe-modal.html',
controller: 'NewRecipeModalController as vm'
}).result.then(function (recipe) {
$rootScope.$broadcast('recipeUpdated', recipe)
})
}
var editRecipe = function (recipe) {
return $modal.open({
resolve: {
recipe: function () {
return recipe
}
},
templateUrl: 'tpls/modals/edit-recipe-modal.html',
controller: 'EditRecipeModalController as vm'
}).result.then(function (recipe) {
$rootScope.$broadcast('recipeUpdated', recipe)
})
}
var expandRecipe = function (recipe) {
return $modal.open({
size: 'lg',
resolve: {
recipe: function () {
return recipe
}
},
templateUrl: 'tpls/modals/expand-recipe-modal.html',
controller: 'ExpandRecipeModalController as vm'
})
}
var deleteRecipe = function (recipe) {
return $modal.open({
resolve: {
recipe: function () {
return recipe
}
},
templateUrl: 'tpls/modals/delete-recipe-modal.html',
controller: 'DeleteRecipeModalController as vm'
}).result.then(function (recipe) {
$rootScope.$broadcast('recipeDeleted', recipe)
})
}
/* Snippet */
var newSnippet = function () {
return $modal.open({
templateUrl: 'tpls/modals/new-snippet-modal.tpl.html',
controller: 'NewSnippetModalController as vm'
}).result.then(function (snippet) {
$rootScope.$broadcast('snippetUpdated', snippet)
})
}
var editSnippet = function (snippet) {
return $modal.open({
resolve: {
snippet: function () {
return snippet
}
},
templateUrl: 'tpls/modals/edit-snippet-modal.tpl.html',
controller: 'EditSnippetModalController as vm'
}).result.then(function (snippet) {
$rootScope.$broadcast('snippetUpdated', snippet)
})
}
var deleteSnippet = function (snippet) {
return $modal.open({
resolve: {
snippet: function () {
return snippet
}
},
templateUrl: 'tpls/modals/delete-snippet-modal.tpl.html',
controller: 'DeleteSnippetModalController as vm'
}).result.then(function (snippet) {
$rootScope.$broadcast('snippetDeleted', snippet)
})
}
var selectSnippet = function (snippet) {
return $modal.open({
templateUrl: 'tpls/modals/select-snippet-modal.html',
controller: 'SelectSnippetModalController as vm'
}).result
}
return {
showAgreement: showAgreement,
showRegulation: showRegulation,
showPP: showPP,
signOut: signOut,
newRecipe: newRecipe,
editRecipe: editRecipe,
deleteRecipe: deleteRecipe,
expandRecipe: expandRecipe,
newSnippet: newSnippet,
editSnippet: editSnippet,
deleteSnippet: deleteSnippet,
selectSnippet: selectSnippet
}
})

View File

@@ -1,552 +0,0 @@
.expand-recipe-modal .expand-editor .editor-pane {
height: 500px;
}
.expand-recipe-modal .expand-editor .editor-pane .ace_editor {
height: 500px;
}
.expand-recipe-modal .expand-editor .preview-pane {
height: 500px;
overflow-y: auto;
}
.new-snippet-modal .ace_editor {
height: 200px;
}
.select-snippet-modal .snippet-list {
list-style: none;
padding: 0;
}
.select-snippet-modal .snippet-list li {
padding: 10px;
border: solid 1px #001a20;
background-color: #003b4a;
border-radius: 5px;
margin-bottom: 5px;
cursor: pointer;
}
.select-snippet-modal .snippet-list li:hover {
background-color: #004b5f;
}
.select-snippet-modal .snippet-list li .ace_editor {
height: 150px;
}
.select-snippet-modal .snippet-list li .call-sign {
color: #d5dfe2;
}
#side-view .nav-control-group {
margin: auto 10px;
}
#side-view .new-block {
margin: 20px auto;
}
#side-view .new-block button {
padding: 10px inherit;
}
#side-view .new-block button:nth-child(1) {
width: 147px;
padding-left: 15px;
text-align: left;
}
#side-view .new-block button:nth-child(2) {
width: 33px;
}
#side-view .new-block .success-menu {
background-color: #167b59;
}
#side-view .new-block .success-menu a {
padding: 5px 15px;
color: #fff;
}
#side-view .new-block .success-menu a.hover,
#side-view .new-block .success-menu a:hover {
background-color: #22bd89;
}
#side-view .new-block .success-menu a.focus,
#side-view .new-block .success-menu a:focus {
background-color: #20b482;
}
#side-view ul.nav.nav-pills {
margin-top: 10px;
}
#side-view ul.nav.nav-pills li a {
padding: 12px 15px;
margin-bottom: 7px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
-webkit-transition: 0.2s;
transition: 0.2s;
}
#side-view ul.nav.nav-pills li.active > a,
#side-view ul.nav.nav-pills .nav-pills > li.active > a:hover,
#side-view ul.nav.nav-pills .nav-pills > li.active > a:focus {
background-color: #004b5f;
}
.botlink {
position: absolute;
bottom: 0;
text-align: center;
}
/*
* ui-select
* http://github.com/angular-ui/ui-select
* Version: 0.11.2 - 2015-03-17T04:08:46.478Z
* License: MIT
*/
.ui-select-highlight {
font-weight: bold;
}
.ui-select-offscreen {
clip: rect(0 0 0 0) !important;
width: 1px !important;
height: 1px !important;
border: 0 !important;
margin: 0 !important;
padding: 0 !important;
overflow: hidden !important;
position: absolute !important;
outline: 0 !important;
left: 0px !important;
top: 0px !important;
}
.ng-dirty.ng-invalid > a.select2-choice {
border-color: #d44950;
}
.select2-result-single {
padding-left: 0;
}
.select2-locked > .select2-search-choice-close {
display: none;
}
.select-locked > .ui-select-match-close {
display: none;
}
body > .select2-container.open {
z-index: 9999;
}
.selectize-input.selectize-focus {
border-color: #007fbb !important;
}
.selectize-control > .selectize-input > input {
width: 100%;
}
.selectize-control > .selectize-dropdown {
width: 100%;
}
.ng-dirty.ng-invalid > div.selectize-input {
border-color: #d44950;
}
.btn-default-focus {
color: #333;
background-color: #ebebeb;
border-color: #adadad;
text-decoration: none;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
box-shadow: inset 0 1px 1px rgba(0,0,0,0.075), 0 0 8px rgba(102,175,233,0.6);
}
.ui-select-bootstrap .ui-select-toggle {
position: relative;
border-radius: $input-border-radius;
}
.ui-select-bootstrap .ui-select-toggle .ui-select-placeholder {
color: #99b2b8;
}
.ui-select-bootstrap .ui-select-toggle > .caret {
position: absolute;
height: 10px;
top: 50%;
right: 10px;
margin-top: -2px;
}
.input-group > .ui-select-bootstrap.dropdown {
/* Instead of relative */
position: static;
}
.input-group > .ui-select-bootstrap > input.ui-select-search.form-control {
border-radius: $input-border-radius;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.ui-select-bootstrap > .ui-select-match > .btn {
/* Instead of center because of .btn */
text-align: left !important;
padding-right: 25px;
border-radius: $input-border-radius;
border: solid 1px #001a20;
}
.ui-select-bootstrap > .ui-select-match > .caret {
position: absolute;
top: 45%;
right: 15px;
}
.ui-select-bootstrap > .ui-select-choices {
width: 100%;
height: auto;
max-height: 200px;
overflow-x: hidden;
margin-top: -1px;
}
body > .ui-select-bootstrap.open {
z-index: 1000;
}
.ui-select-multiple.ui-select-bootstrap {
height: auto;
padding: 3px 3px 0 10px;
}
.ui-select-multiple.ui-select-bootstrap.open {
border-color: #52dcff;
outline: 0;
box-shadow: inset 0 1px 1px rgba(0,0,0,0.075), 0 0 8px rgba(82,220,255,0.6);
}
.ui-select-multiple.ui-select-bootstrap input.ui-select-search {
background-color: transparent !important;
border: none;
outline: none;
height: 1.666666em;
margin-bottom: 3px;
}
.ui-select-multiple.ui-select-bootstrap .ui-select-match .close {
font-size: 1.6em;
line-height: 0.75;
}
.ui-select-multiple.ui-select-bootstrap .ui-select-match-item {
outline: 0;
margin: 0 3px 3px 0;
}
.ui-select-multiple .ui-select-match-item {
position: relative;
}
.ui-select-multiple .ui-select-match-item.dropping-before:before {
content: "";
position: absolute;
top: 0;
right: 100%;
height: 100%;
margin-right: 2px;
border-left: 1px solid #428bca;
}
.ui-select-multiple .ui-select-match-item.dropping-after:after {
content: "";
position: absolute;
top: 0;
left: 100%;
height: 100%;
margin-left: 2px;
border-right: 1px solid #428bca;
}
.ui-select-bootstrap .ui-select-choices-row>a {
display: block;
padding: 3px 20px;
clear: both;
font-weight: 400;
line-height: 1.42857143;
color: #99b2b8;
white-space: nowrap;
}
.ui-select-bootstrap .ui-select-choices-row>a:hover,
.ui-select-bootstrap .ui-select-choices-row>a:focus {
text-decoration: none;
color: #fff;
background-color: #004b5f;
}
.ui-select-bootstrap .ui-select-choices-row.active>a {
color: #fff;
text-decoration: none;
outline: 0;
background-color: #004b5f;
}
.ui-select-bootstrap .ui-select-choices-row.disabled>a,
.ui-select-bootstrap .ui-select-choices-row.active.disabled>a {
color: #777;
cursor: not-allowed;
background-color: #fff;
}
.ui-select-match.ng-hide-add,
.ui-select-search.ng-hide-add {
display: none !important;
}
.ui-select-bootstrap.ng-dirty.ng-invalid > button.btn.ui-select-match {
border-color: #d44950;
}
.auth-state .panel {
margin-top: 50px;
}
.auth-state h1 {
margin: 15px 0;
}
.auth-state .auth-control {
margin: 10px 0;
}
.home-state {
padding: 10px;
}
.home-state p {
margin: 5px auto 15px;
}
.home-state ol {
margin: 35px auto;
}
.home-state li {
margin-bottom: 25px;
}
.settings-state .panel {
margin-top: 15px;
}
.settings-state h1 {
margin: 30px 0;
}
.settings-state .section h4 {
margin-bottom: 15px;
}
.snippets-list-state {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.snippets-list-state .left-pane {
border-right: 1px solid #001a20;
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 275px;
overflow: hidden;
}
.snippets-list-state .left-pane .snippet-search {
position: absolute;
top: 0;
height: 50px;
left: 0;
right: 0;
border-right: 1px solid #001a20;
padding: 7px 5px;
}
.snippets-list-state .left-pane .snippet-list {
position: absolute;
top: 50px;
bottom: 0;
left: 0;
right: 0;
overflow-x: hidden;
overflow-y: auto;
list-style: none;
padding: 0;
}
.snippets-list-state .left-pane .snippet-list li {
cursor: pointer;
padding: 5px;
border-right: 1px solid #001a20;
border-bottom: 1px solid #001a20;
}
.snippets-list-state .left-pane .snippet-list li:nth-child(even) {
background-color: #002b36;
}
.snippets-list-state .left-pane .snippet-list li:nth-child(odd) {
background-color: #00323f;
}
.snippets-list-state .left-pane .snippet-list li h4 {
margin: 0;
}
.snippets-list-state .left-pane .snippet-list li:hover {
background-color: #004b5f;
}
.snippets-list-state .left-pane .snippet-list li p {
margin: 0;
}
.snippets-list-state .left-pane .snippet-list li p.call-sign {
font-size: 0.8em;
}
.snippets-list-state .left-pane .snippet-list li p.created-at {
font-size: 0.8em;
opacity: 0.8;
}
.snippets-list-state .left-pane .snippet-list li.active {
color: #fff;
background-color: #088cff;
}
.snippets-list-state .left-pane .snippet-list li.active a {
color: #fff;
}
.snippets-list-state .right-pane {
position: absolute;
top: 0;
bottom: 0;
left: 275px;
right: 0;
overflow-x: hidden;
overflow-y: auto;
background-color: #00323f;
}
.snippets-detail-state {
position: absolute;
top: 0;
width: 100%;
bottom: 0;
overflow: hidden;
}
.snippets-detail-state .detail-header {
position: absolute;
top: 0;
width: 100%;
background-color: #003d4d;
padding: 5px 10px;
height: 50px;
border-bottom: solid 1px #001a20;
}
.snippets-detail-state .detail-header .detail-header-title {
color: #d5dfe2;
line-height: 40px;
font-size: 1.2em;
}
.snippets-detail-state .detail-header .detail-header-title small {
font-size: 0.6em;
color: #99b2b8;
}
.snippets-detail-state .detail-header .detail-header-control {
padding: 3px;
}
.snippets-detail-state .detail-body {
position: absolute;
top: 50px;
width: 100%;
bottom: 0;
padding: 5px 10px;
overflow-y: auto;
}
.snippets-detail-state .detail-body .ace_editor {
min-height: 300px;
border: solid 1px $border-color;
border-radius: 5px;
margin-bottom: 5px;
}
.tags {
word-break: break-all;
}
.tags a {
margin: 0 2px;
}
#side-view {
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 200px;
background-color: #002b36;
border-right: solid 2px #004b5f;
box-sizing: border-box;
padding: 10px 0 10px 10px;
}
#main-view {
position: absolute;
top: 0;
bottom: 0;
left: 200px;
right: 0;
overflow-x: hidden;
overflow-y: auto;
background-color: $bgDarker;
}
.marked h1,
.marked h2,
.marked h3,
.marked h4,
.marked h5 {
margin: 0.75em 0;
}
.marked h1:nth-child(1),
.marked h2:nth-child(1),
.marked h3:nth-child(1),
.marked h4:nth-child(1),
.marked h5:nth-child(1) {
margin-top: 0;
}
.marked code {
background-color: #003644;
color: #fff;
border: 1px solid #001a20;
border-radius: 5px;
box-shadow: 0 1px 1px rgba(0,0,0,0.05);
padding: 5px;
line-height: 200%;
}
.marked pre {
margin-bottom: 10px;
background-color: #003644;
color: #fff;
border: 1px solid #001a20;
border-radius: 5px;
box-shadow: 0 1px 1px rgba(0,0,0,0.05);
padding: 5px;
}
.marked pre >code {
background-color: transparent;
color: inherit;
border: none;
border-radius: 0;
box-shadow: none;
padding: 0;
line-height: inherit;
}
.marked blockquote {
font-size: 1em;
border-left: 5px solid #6494ed;
}
.marked a {
text-decoration: underline;
color: #6494ed;
}
.marked table {
width: 100%;
max-width: 100%;
margin-bottom: $line-height-computed;
border: 1px solid #001a20;
margin-bottom: 10px;
}
.marked table > thead > tr > th,
.marked table > tbody > tr > th,
.marked table > tfoot > tr > th,
.marked table > thead > tr > td,
.marked table > tbody > tr > td,
.marked table > tfoot > tr > td {
padding: 10px;
line-height: $line-height-base;
vertical-align: top;
border-top: 1px solid #001a20;
border-right: 1px solid #001a20;
}
.marked table > thead > tr > th:nth-last-child(1),
.marked table > tbody > tr > th:nth-last-child(1),
.marked table > tfoot > tr > th:nth-last-child(1),
.marked table > thead > tr > td:nth-last-child(1),
.marked table > tbody > tr > td:nth-last-child(1),
.marked table > tfoot > tr > td:nth-last-child(1) {
border-right: none;
}
.marked table > thead > tr > th {
vertical-align: bottom;
border-bottom: 2px solid #001a20;
}
.marked table > caption + thead,
.marked table > colgroup + thead,
.marked table > thead:first-child {
background-color: #004b5f;
}
.marked table > caption + thead > tr:first-child > th,
.marked table > colgroup + thead > tr:first-child > th,
.marked table > thead:first-child > tr:first-child > th,
.marked table > caption + thead > tr:first-child > td,
.marked table > colgroup + thead > tr:first-child > td,
.marked table > thead:first-child > tr:first-child > td {
border-top: 0;
}
.marked table > tbody >tr:nth-child(odd) {
background-color: #002b36;
}
.marked table > tbody >tr:nth-child(even) {
background-color: #003644;
}
.short {
height: 500px;
overflow-y: auto;
}

View File

@@ -1,105 +0,0 @@
@import '../../shared/styles/_vars'
@import '../../shared/styles/mixins/*'
@import 'modals/*'
@import 'directives/*'
@import 'states/*'
#side-view
position:absolute
top: 0
bottom: 0
left: 0
width: 200px
background-color: $baseBackgroundColor
border-right solid 2px $backgroundColorSelected
box-sizing: border-box
padding: 10px 0 10px 10px
#main-view
position:absolute
top: 0
bottom: 0
left: 200px
right: 0
overflow-x: hidden
overflow-y: auto
background-color $bgDarker
.marked
h1, h2, h3, h4, h5
margin 0.75em 0
&:nth-child(1)
margin-top 0
code
background-color lighten($baseBackgroundColor, 3%)
color $textColorSelected
border 1px solid $baseBorderColor
border-radius 5px
box-shadow 0 1px 1px rgba(0, 0, 0, .05)
padding 5px
line-height 200%
pre
margin-bottom 10px
background-color lighten($baseBackgroundColor, 3%)
color $textColorSelected
border 1px solid $baseBorderColor
border-radius 5px
box-shadow 0 1px 1px rgba(0, 0, 0, .05)
padding 5px
>code
background-color transparent
color inherit
border none
border-radius 0
box-shadow none
padding 0
line-height inherit
blockquote
font-size 1em
border-left 5px solid $textColorInfo
a
text-decoration underline
color $textColorInfo
table
width 100%
max-width 100%
margin-bottom $line-height-computed
border 1px solid $table-border-color
margin-bottom 10px
// Cells
> thead,
> tbody,
> tfoot
> tr
> th,
> td
padding 10px
line-height $line-height-base
vertical-align top
border-top 1px solid $table-border-color
border-right 1px solid $table-border-color
&:nth-last-child(1)
border-right none
> thead > tr > th
vertical-align bottom
border-bottom 2px solid $table-border-color
> caption + thead,
> colgroup + thead,
> thead:first-child
background-color $backgroundColorSelected
> tr:first-child
> th,
> td
border-top 0
> tbody
>tr
&:nth-child(odd)
background-color $baseBackgroundColor
&:nth-child(even)
background-color lighten($baseBackgroundColor, 3%)
.short
height 500px
overflow-y auto

View File

@@ -1,38 +0,0 @@
#side-view
.nav-control-group
margin auto 10px
.new-block
margin 20px auto
button
padding 10px inherit
button:nth-child(1)
width 147px
padding-left 15px
text-align left
button:nth-child(2)
width 33px
.success-menu
background-color darken($brand-success, 35%)
a
padding 5px 15px
color $textColorSelected
&.hover, &:hover
background-color $brand-success
&.focus, &:focus
background-color darken($brand-success, 5%)
ul.nav.nav-pills
margin-top 10px
li a
padding 12px 15px
margin-bottom 7px
border-top-right-radius 0
border-bottom-right-radius 0
transition 0.2s
li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus{
background-color: $backgroundColorSelected
}
.botlink
position absolute
bottom 0
text-align center

View File

@@ -1,50 +0,0 @@
<div class="current-user">
<div ng-if="vm.currentUser">
<img width="30" class="img-circle" ng-src="http://www.gravatar.com/avatar/{{ vm.currentUser.email | gravatar }}">
<a href ng-bind="vm.currentUser.name"></a>
<span class="nav-control-group pull-right">
<a ui-sref="settings" class="btn btn-sm btn-default" ui-sref-active="active"><i class="fa fa-gears fa-fw"></i></a>
<a href class="btn btn-sm btn-default" ng-click="vm.signOut()"><i class="fa fa-sign-out fa-fw"></i></a>
</span>
</div>
<div ng-if="!vm.currentUser">
<span>Guest</span>
<span class="nav-control-group pull-right">
<a class="btn btn-sm btn-default" ui-sref="auth.register"><i class="fa fa-user-plus fa-fw"></i></a>
<a class="btn btn-sm btn-default" ui-sref="auth.signin"><i class="fa fa-sign-in fa-fw"></i></a>
</span>
</div>
</div>
<div class="new-block">
<div class="btn-group" dropdown>
<button ng-disabled="!vm.isAuthenticated" btn-new-snippet type="button" class="btn btn-success"><i class="fa fa-plus-square-o fa-fw"></i> New Snippet</button>
<button ng-disabled="!vm.isAuthenticated" type="button" class="btn btn-success dropdown-toggle" dropdown-toggle>
<span class="caret"></span>
<span class="sr-only">Split button!</span>
</button>
<ul class="dropdown-menu success-menu" role="menu">
<li><a href btn-new-recipe><i class="fa fa-bookmark-o fa-fw"></i> New Recipe</a></li>
</ul>
</div>
</div>
<ul class="nav nav-pills nav-stacked">
<li ui-sref-active="active">
<a ui-sref="home"><i class="fa fa-home fa-fw"></i> Home</a>
</li>
<li ui-sref-active="active">
<a ui-sref="snippets"><i class="fa fa-code fa-fw"></i> Snippets</a>
</li>
<li ui-sref-active="active">
<a ui-sref="recipes"><i class="fa fa-bookmark-o fa-fw"></i> Recipes</a>
</li>
</ul>
<div class="botlink">
<a href ng-click="vm.showRegulation()">利用規約</a><br>
<a href ng-click="vm.showPP()">プライバシーポリシー</a>
</div>

View File

@@ -1,121 +0,0 @@
<div class="new-snippet-modal">
<div class="modal-header">
<h4>プライバシーポリシー</h4>
</div>
<div class="modal-body marked short">
<h1>CodeXenプライバシーポリシー</h1>
<p>MAISIN&amp;CO.株式会社以下、「当社」といいます。は、本ウェブサイト上で提供するCodeXen以下、「本サービス」といいます。におけるプライバシー情報の取扱いについて、以下のとおりプライバシーポリシー以下「本ポリシー」といいます。を定めます。</p>
<h3><a id="user-content-第1条プライバシー情報" class="anchor" href="#第1条プライバシー情報" aria-hidden="true"><span class="octicon octicon-link"></span></a>第1条プライバシー情報</h3>
<p> プライバシー情報のうち「個人情報」とは、個人情報保護法にいう「個人情報」を指すものとし、生存する個人に関する情報であって、当該情報に含まれる氏名、生年月日、住所、電話番号、連絡先その他の記述等により特定の個人を識別できる情報を指します。</p>
<p> プライバシー情報のうち「履歴情報および特性情報」とは、上記に定める「個人情報」以外のものをいい、ご利用頂いたサービスやご購入頂いた商品、ご覧になったページや広告の履歴、ユーザーが検索された検索キーワード、ご利用日時、ご利用の方法、ご利用環境、郵便番号や性別、職業、年齢、ユーザーのIPアドレス、クッキー情報、位置情報、端末の個体識別情報などを指します。</p>
<h3><a id="user-content-第2条プライバシー情報の収集方法" class="anchor" href="#第2条プライバシー情報の収集方法" aria-hidden="true"><span class="octicon octicon-link"></span></a>第2条(プライバシー情報の収集方法)</h3>
<p> 当社は、ユーザーが利用登録をする際に氏名、生年月日、住所、電話番号、メールアドレス、銀行口座番号、クレジットカード番号、運転免許証番号などの個人情報をお尋ねすることがあります。また、ユーザーと提携先などとの間でなされたユーザーの個人情報を含む取引記録や、決済に関する情報を当社の提携先(情報提供元,広告主,広告配信先などを含みます。以下、「提携先」といいます。)などから収集することがあります。</p>
<p> 当社は、ユーザーについて、利用したサービスやソフトウエア、購入した商品、閲覧したページや広告の履歴、検索した検索キーワード、利用日時、利用方法、利用環境携帯端末を通じてご利用の場合の当該端末の通信状態、利用に際しての各種設定情報なども含みます、IPアドレス、クッキー情報、位置情報、端末の個体識別情報などの履歴情報および特性情報を、ユーザーが当社や提携先のサービスを利用しまたはページを閲覧する際に収集します。</p>
<h3><a id="user-content-第3条個人情報を収集利用する目的" class="anchor" href="#第3条個人情報を収集利用する目的" aria-hidden="true"><span class="octicon octicon-link"></span></a>第3条(個人情報を収集・利用する目的)</h3>
<p> 当社が個人情報を収集・利用する目的は、以下のとおりです。</p>
<p>1ユーザーに自分の登録情報の閲覧や修正、利用状況の閲覧を行って頂く為に、氏名、住所、連絡先、支払方法などの登録情報、利用されたサービスや購入された商品、およびそれらの代金などに関する情報を表示する目的</p>
<p>2ユーザーにお知らせや連絡をするためにメールアドレスを利用する場合やユーザーに商品を送付したり必要に応じて連絡したりする為、氏名や住所などの連絡先情報を利用する目的</p>
<p>3ユーザーの本人確認を行うために、氏名、生年月日、住所、電話番号、銀行口座番号、クレジットカード番号、運転免許証番号、配達証明付き郵便の到達結果などの情報を利用する目的</p>
<p>4ユーザーに代金を請求するために、購入された商品名や数量、利用されたサービスの種類や期間、回数、請求金額、氏名、住所、銀行口座番号やクレジットカード番号などの支払に関する情報などを利用する目的</p>
<p>5ユーザーが簡便にデータを入力できるようにする為に、当社に登録されている情報を入力画面に表示させたり、ユーザーのご指示に基づいて他のサービスなど提携先が提供するものも含みますに転送したりする目的</p>
<p>6代金の支払を遅滞したり第三者に損害を発生させたりするなど、本サービスの利用規約に違反したユーザーや、不正・不当な目的でサービスを利用しようとするユーザーの利用を停止するために、利用態様、氏名や住所など個人を特定するための情報を利用する目的</p>
<p>7ユーザーからのお問い合わせに対応する為、お問い合わせ内容や代金の請求に関する情報など当社がユーザーに対してサービスを提供するにあたって必要となる情報や、ユーザーのサービス利用状況、連絡先情報などを利用する目的</p>
<p>8利用者の皆様の行動、性別、当社内でのアクセス履歴などを用いたターゲティング広告の配信</p>
<p>9当社上で、個人を特定できない範囲においての統計情報の作成および利用</p>
<p>10当社の他サービスへの情報の連携・情報の共有</p>
<p>11当社の新規開発に必要なデータの解析や分析</p>
<p>12当社が提携している先への個人を特定できず会員の許諾を得た範囲内での情報の提供</p>
<p>13上記の利用目的に付随する目的</p>
<h3><a id="user-content-第4条個人情報の第三者提供" class="anchor" href="#第4条個人情報の第三者提供" aria-hidden="true"><span class="octicon octicon-link"></span></a>第4条(個人情報の第三者提供)</h3>
<p> 当社は、次に掲げる場合を除いて、あらかじめユーザーの同意を得ることなく、第三者に個人情報を提供することはありません。ただし、個人情報保護法その他の法令で認められる場合を除きます。</p>
<p>1法令に基づく場合</p>
<p>2人の生命、身体または財産の保護のために必要がある場合であって、本人の同意を得ることが困難であるとき</p>
<p>3公衆衛生の向上または児童の健全な育成の推進のために特に必要がある場合であって、本人の同意を得ることが困難であるとき</p>
<p>4国の機関もしくは地方公共団体またはその委託を受けた者が法令の定める事務を遂行することに対して協力する必要がある場合であって、本人の同意を得ることにより当該事務の遂行に支障を及ぼすおそれがあるとき</p>
<p>5予め次の事項を告知あるいは公表をしている場合</p>
<ul>
<li>利用目的に第三者への提供を含むこと</li>
<li>第三者に提供されるデータの項目</li>
<li>第三者への提供の手段または方法</li>
</ul>
<p> 前項の定めにかかわらず、次に掲げる場合は第三者には該当しないものとします。</p>
<p>(ⅰ)当社が利用目的の達成に必要な範囲内において個人情報の取扱いの全部または一部を委託する場合</p>
<p>(ⅱ)合併その他の事由による事業の承継に伴って個人情報が提供される場合</p>
<p>(ⅲ)個人情報を特定の者との間で共同して利用する場合であって、その旨並びに共同して利用される個人情報の項目、共同して利用する者の範囲、利用する者の利用目的および当該個人情報の管理について責任を有する者の氏名または名称について、あらかじめ本人に通知し、または本人が容易に知り得る状態に置いているとき</p>
<h3><a id="user-content-第5条個人情報の開示" class="anchor" href="#第5条個人情報の開示" aria-hidden="true"><span class="octicon octicon-link"></span></a>第5条(個人情報の開示)</h3>
<p> 当社は、本人から個人情報の開示を求められたときは、本人に対し、一ヶ月以内にこれを開示します。ただし、開示することにより次のいずれかに該当する場合は、その全部または一部を開示しないこともあり、開示しない決定をした場合には、その旨を遅滞なく通知します。なお、個人情報の開示に際しては,1件あたり2,500円の手数料を申し受けます。</p>
<p>1本人または第三者の生命、身体、財産その他の権利利益を害するおそれがある場合</p>
<p>2当社の業務の適正な実施に著しい支障を及ぼすおそれがある場合</p>
<p>3本人または第三者がその他法令に違反することとなる場合
前項の定めにかかわらず、履歴情報および特性情報などの個人情報以外の情報については、原則として開示いたしません。</p>
<h3><a id="user-content-第6条個人情報の訂正および削除" class="anchor" href="#第6条個人情報の訂正および削除" aria-hidden="true"><span class="octicon octicon-link"></span></a>第6条(個人情報の訂正および削除)</h3>
<p> ユーザーは、当社の保有する自己の個人情報が誤った情報である場合には、当社が定める手続きにより、当社に対して個人情報の訂正または削除を請求することができます。</p>
<p> 当社は、ユーザーから前項の請求を受けてその請求に応じる必要があると判断した場合には、遅滞なく、当該個人情報の訂正または削除を行い、これをユーザーに通知します。</p>
<h3><a id="user-content-第7条個人情報の利用停止等" class="anchor" href="#第7条個人情報の利用停止等" aria-hidden="true"><span class="octicon octicon-link"></span></a>第7条(個人情報の利用停止等)</h3>
<p> 当社は、本人から、個人情報が、利用目的の範囲を超えて取り扱われているという理由、または不正の手段により取得されたものであるという理由により、その利用の停止または消去(以下、「利用停止等」といいます。)を求められた場合には、遅滞なく必要な調査を行い、その結果に基づき、個人情報の利用停止等を行い、その旨本人に通知します。ただし、個人情報の利用停止等に多額の費用を有する場合その他利用停止等を行うことが困難な場合であって、本人の権利利益を保護するために必要なこれに代わるべき措置をとれる場合は、この代替策を講じます。</p>
<h3><a id="user-content-第8条プライバシーポリシーの変更" class="anchor" href="#第8条プライバシーポリシーの変更" aria-hidden="true"><span class="octicon octicon-link"></span></a>第8条(プライバシーポリシーの変更)</h3>
<p> 本ポリシーの内容は、ユーザーに通知することなく、変更することができるものとします。</p>
<p> 当社が別途定める場合を除いて、変更後のプライバシーポリシーは、本ウェブサイトに掲載したときから効力を生じるものとします。</p>
<h3><a id="user-content-第9条お問い合わせ窓口" class="anchor" href="#第9条お問い合わせ窓口" aria-hidden="true"><span class="octicon octicon-link"></span></a>第9条(お問い合わせ窓口)</h3>
<p>本ポリシーに関するお問い合わせは、下記の窓口までお願い致します。</p>
<ul>
<li>社名MAISIN&amp;CO.株式会社</li>
<li>Eメールアドレスinfo@maisin.co</li>
</ul>
</div>
<div class="modal-footer">
<button ng-click="vm.cancel()" type="button" name="button" class="btn btn-default">Close</button>
</div>
</div>

View File

@@ -1,264 +0,0 @@
<div class="new-snippet-modal">
<div class="modal-header">
<h4>利用規約</h4>
</div>
<div class="modal-body marked short">
<h1>CodeXen利用規約</h1>
<p>定義</p>
<p> この利用規約以下、「本規約」といいます。はMAISIN&amp;CO.株式会社以下、「当社」といいます。がこのcodexen.github.ioのドメインおよびサブドメインのウェブサイト以下、「当サイト」といます。において公開する、またはCodeXen、またはそれに付随する名称で提供するサービス以下、「本サービス」といいます。の利用条件を定めるものです。登録ユーザーの皆さま以下、「ユーザー」といいます。には、本規約に従って本サービスをご利用頂きます。</p>
<p> アプリケーションとは、本サービスの利用を通してユーザーが使用するアプリケーションを意味します。</p>
<p>作成:平成5月22日</p>
<h3><a id="user-content-第1条規約の適用" class="anchor" href="#第1条規約の適用" aria-hidden="true"><span class="octicon octicon-link"></span></a>第1条規約の適用</h3>
<p> ユーザーが、当サイトにアクセスし、本サービスを利用される場合、本規約に同意したものとみなされます。 本利用規約に同意頂けない場合は、当サイトへのアクセス、または本サービスをご利用頂くことは出来ません。</p>
<p> 本サービスにつき別途定めるプライバシーポリシー、ガイドラインその他の規約(以下「個別規約」といいます。)も、本規約の一部を構成するものとします。 本規約の定めと個別規約の定めが異なる場合は、当該個別規約の定めが優先して適用されるものとします。</p>
<h3><a id="user-content-第2条利用登録" class="anchor" href="#第2条利用登録" aria-hidden="true"><span class="octicon octicon-link"></span></a>第2条利用登録</h3>
<p> 登録希望者が当社の定める方法によって利用登録を申請し、当社がこれを承認することによって利用登録が完了するものとします。</p>
<p> 当社は、利用登録の申請者に以下の事由があると判断した場合、利用登録の申請を承認しないことがあり、その理由については一切の開示義務を負わないものとします。なお、未成年者である場合は、親権者など法定代理人の同意を得たうえで本サービスを利用しなければなりません。</p>
<p>1本規約に違反したことがある者からの申請である場合</p>
<p>2利用登録の申請に際して虚偽の事項を届け出た場合</p>
<p>3 未成年者、成年被後見人、被保佐人または被補助人であり、法定代理人、後見人、保佐人または補助人の同意を得ていなかった場合</p>
<p>4反社会的勢力等である、または資金提供その他を通じて反社会的勢力等の維持、運営もしくは経営に協力もしくは関与する等反社会的勢力との何らかの交流もしくは関与を行っていると当社が判断した場合</p>
<p>5その他、当社が利用登録を相当でないと判断した場合</p>
<h3><a id="user-content-第3条ユーザーidおよびパスワードの管理" class="anchor" href="#第3条ユーザーidおよびパスワードの管理" aria-hidden="true"><span class="octicon octicon-link"></span></a>第3条ユーザーIDおよびパスワードの管理</h3>
<p> ユーザーは、自己の責任において、本サービスのユーザーIDおよびパスワードを管理するものとします。</p>
<p> ユーザーは、いかなる場合にも、ユーザーIDおよびパスワードを第三者に譲渡または貸与することはできません。当社は、ユーザーIDとパスワードの組み合わせが登録情報と一致してログインされた場合には、そのユーザーIDを登録しているユーザー自身による利用とみなします。</p>
<h3><a id="user-content-第4条アプリケーションの登録" class="anchor" href="#第4条アプリケーションの登録" aria-hidden="true"><span class="octicon octicon-link"></span></a>第4条アプリケーションの登録</h3>
<p> ユーザーは、本サービス上に定める当社所定の手続きに従い、アプリケーション毎にその登録を申し込むものとします。ただし、1アカウントにつき登録可能なアプリケーションの数は当社が別途定めるところによるものとします。</p>
<p> 前項の申込みに対し、本サービス上に登録の完了を示す旨の表示がされた時点をもって、アプリケーションの登録は完了し、ユーザーは当該アプリケーションの利用ができるものとします。 アプリケーションの登録をしたユーザーが、その登録期間中、ユーザー資格を喪失した場合は、その理由を問わず当然に全てのアプリケーションの登録も抹消されるものとし、ユーザーは予めこれに同意するものとします。</p>
<h3><a id="user-content-第5条利用料金および支払方法" class="anchor" href="#第5条利用料金および支払方法" aria-hidden="true"><span class="octicon octicon-link"></span></a>第5条利用料金および支払方法</h3>
<p> ユーザーは、本サービス利用の対価として、当社が別途定め、本サービスに表示する利用料金を、当社が指定する方法により支払うものとします。</p>
<p> ユーザーが利用料金の支払を遅滞した場合には、支払期日の翌日から、支払いの日までの日数について、年利14.6%の割合による遅延損害金を支払うものとします。その際支払いに伴う手数料等はユーザーが負担することとします。</p>
<h3><a id="user-content-第6条禁止事項" class="anchor" href="#第6条禁止事項" aria-hidden="true"><span class="octicon octicon-link"></span></a>第6条禁止事項</h3>
<p> ユーザーは、本サービスの利用にあたり、以下の行為をしてはなりません。</p>
<p>1法令または公序良俗に違反する行為</p>
<p>2犯罪行為に関連する行為</p>
<p>3当社のサーバーまたはネットワークの機能を破壊したり、妨害したりする行為</p>
<p>4当社のサービスの運営を妨害するおそれのある行為</p>
<p>5他のユーザーに関する個人情報等を収集または蓄積する行為</p>
<p>6他のユーザーに成りすます行為</p>
<p>7当社のサービスに関連して、反社会的勢力に対して直接または間接に利益を供与する行為</p>
<p>8当社、本サービスの他の利用者または第三者の知的財産権、肖像権、プライバシー、名誉その他の権利または利益を侵害する行為</p>
<p>9過度に暴力的な表現、露骨な性的表現、人種、国籍、信条、性別、社会的身分、門地等による差別につながる表現、自殺、自傷行為、薬物乱用を誘引または助長する表現、その他反社会的な内容を含み他人に不快感を与える表現を、投稿または送信する行為</p>
<p>10営業、宣伝、広告、勧誘、その他営利を目的とする行為当社の認めたものを除きます。、性行為やわいせつな行為を目的とする行為、面識のない異性との出会いや交際を目的とする行為、他のお客様に対する嫌がらせや誹謗中傷を目的とする行為、その他本サービスが予定している利用目的と異なる目的で本サービスを利用する行為</p>
<p>11宗教活動または宗教団体への勧誘行為</p>
<p>12当社の著作物や当サービスのソースコード等を複製・編集し、営利目的の著作物を作成、または販売する行為</p>
<p>13その他、当社が不適切と判断する行為</p>
<h3><a id="user-content-第7条本サービスの提供の停止等" class="anchor" href="#第7条本サービスの提供の停止等" aria-hidden="true"><span class="octicon octicon-link"></span></a>第7条本サービスの提供の停止等</h3>
<p> 当社は、以下のいずれかの事由があると判断した場合、ユーザーに事前に通知することなく本サービスの全部または一部の提供を停止または中断することができるものとします。</p>
<p>1本サービスにかかるコンピュータシステムの保守点検または更新を行う場合</p>
<p>2地震、落雷、火災、停電または天災などの不可抗力により、本サービスの提供が困難となった場合</p>
<p>3コンピュータまたは通信回線等が事故により停止した場合</p>
<p>4外部から攻撃を受け、本サービスの継続が困難になった場合</p>
<p>5その他、当社が本サービスの提供が困難と判断した場合
当社は、本サービスの提供の停止または中断により、ユーザーまたは第三者が被ったいかなる不利益または損害について、理由を問わず一切の責任を負わないものとし、返金も行わないものとします。</p>
<h3><a id="user-content-第8条コンテンツ及び知的財産権の帰属等" class="anchor" href="#第8条コンテンツ及び知的財産権の帰属等" aria-hidden="true"><span class="octicon octicon-link"></span></a>第8条コンテンツ及び知的財産権の帰属等</h3>
<p> 「コンテンツ」とは、プログラム、ソースコード、API、文章、音楽、音声、画像、動画、その他の情報をいい、本サービスを通じてアクセスすることができるコンテンツを「サービスコンテンツ」、ユーザーが本サービスを利用して送信等したコンテンツデータ、サービスおよび下記に定めるアプリケーションを含みます。を「ユーザーコンテンツ」とそれぞれいいます。</p>
<p> 「知的財産権」とは、著作権、特許権、実用新案権、商標権、意匠権その他の知的財産権をいい、それらの権利を取得しまたはそれらの権利につき登録等を出願する権利を含みます。</p>
<p>1本サービスおよびサービスコンテンツに関する知的財産権その他の権利はすべて当社または当社に使用許諾している者に帰属しており、本規約に基づく本サービスの利用の許諾は、本サービスに関する当社または当社に使用許諾している者の知的財産権の使用許諾を意味するものではありません。</p>
<p>2当社は、当社が提供するサービスコンテンツについて、ユーザーに対し、本サービスの利用を唯一の目的とする、譲渡および再許諾不可能な非独占的利用権を付与します。 ユーザーは、ユーザーコンテンツを、本サービスが予定している態様を超えて利用(複製、複写、改変、第三者への再許諾その他のあらゆる利用を含みます。)することはできません。</p>
<p>3当社はサービスコンテンツおよびユーザーコンテンツのバックアップを行う義務を負わないものとします。ユーザーは、ユーザーコンテンツのバックアップが必要な場合には、自己の費用と責任でこれを行うものとします。</p>
<p>4当社は、法令または本規約の遵守状況などを確認する必要がある場合、ユーザーコンテンツの内容を確認することができるものとします。</p>
<p>5当社は、本サービスに当社または第三者の広告を掲載することができるものとします。</p>
<h3><a id="user-content-第9条利用制限および登録抹消" class="anchor" href="#第9条利用制限および登録抹消" aria-hidden="true"><span class="octicon octicon-link"></span></a>第9条利用制限および登録抹消</h3>
<p> 当社は、以下の場合には、事前の通知なく、投稿データを削除し、ユーザーに対して本サービスの全部もしくは一部の利用を制限しまたはユーザーとしての登録を抹消することができるものとします。</p>
<p>1ユーザーが本規約のいずれかの条項に違反した場合</p>
<p>2ユーザーが登録事項に虚偽の事実があることが判明した場合</p>
<p>3破産、民事再生、会社更生または特別清算の手続開始決定等の申立がなされたとき</p>
<p>4ユーザーが登録後1年間以上本サービスの利用がない場合</p>
<p>5当社からの問い合わせその他の回答を求める連絡に対して、ユーザー側から30日間以上応答がない場合</p>
<p>6通常の範囲でのWebブラウザもしくは当社が提供するアプリケーションによる使用以外での特殊なアクセスを行った場合</p>
<p>7大量のリクエストを本サイトに対して発行し、システムに対する負荷をかける行為</p>
<p>8不正アクセスやクラッキングに相当する行為</p>
<p>9法令に触れる行為</p>
<p>10犯罪に関わる行為</p>
<p>11著作権、特許権等の知的財産権を侵害する行為</p>
<p>12公序良俗に反する行為</p>
<p>13社会的に不適切な行動と解される行為</p>
<p>14第6条に該当する場合</p>
<p>15その他、当社が本サービスの利用を適当でないと判断した場合 前項各号のいずれかに該当した場合、ユーザーは,当然に当社に対する一切の債務について期限の利益を失い、その時点において負担する一切の債務を直ちに一括して弁済しなければなりません。
当社は、本条に基づき当社が行った行為によりユーザーに生じた損害について、一切の責任を負いません。</p>
<h3><a id="user-content-第10条一般条項" class="anchor" href="#第10条一般条項" aria-hidden="true"><span class="octicon octicon-link"></span></a>第10条一般条項</h3>
<p>. 通知</p>
<p>(1)本サービスに関する当社からユーザーへの通知・連絡は、当社が運営するウェブサイト内の適宜の場所への掲示その他、当社が適当と判断する方法により行なうものとします。 当
社からの通知・連絡が不着であったり遅延したりといったことによって生じる損害につい
て、当社は一切の責任を負いません。</p>
<p>(2)本サービスに関するユーザーから当社への通知・連絡は、当社が運営するウェブサイト内
の適宜の場所に設置するお問い合わせフォームの送信または当社が指定する方法により行
うものとします。ユーザーから通知・連絡があった場合、当社は、当社所定の方法により、
ユーザーの本人確認を行うことができるものとします。また、ユーザーからの通知・連絡に対
する回答方法については、その都度当社が最適と考える方法により回答することができる
ものとし、その回答方法をユーザーが指定することはできないものとします。</p>
<p>. 譲渡禁止</p>
<p> ユーザーは、当社の書面による事前の承諾なく、本規約に基づく契約上の地位または本規約に基づく権利もしくは義務につき、第三者に対し、譲渡、移転、担保設定、貸与、その他の処分をすることはできません。</p>
<p>. 事業譲渡</p>
<p> 当社が本サービスに係る事業を第三者に譲渡する場合(事業譲渡、会社分割その他本サービスが移転する一切の場合を含む。)には、当該事業の譲渡に伴い、ユーザーの本規約に基づく契約上の地位、本規約に基づく権利・義務およびアカウント登録に伴い登録された情報その他の情報を、当社は当該事業の譲受人に譲渡することができるものとし、ユーザーは、かかる譲渡につき予め承諾するものとします。</p>
<p>. 分離可能性</p>
<p> 本規約のいずれかの条項またはその一部が、消費者契約法その他の法令等により無効と判断された場合であっても、本規約の残りの規定および一部が無効と判断された規定の残りの部分は、継続して有効に存続し、当該無効とされた条項またはその一部を、有効とするために必要な範囲で修正し、最大限、当該無効とされた条項またはその一部の趣旨および法律的経済的に同等の効果が確保されるよう解釈されるものとします。</p>
<p>. 定めのない事項等</p>
<p> 本規約に定めのない事項または本規約の解釈に疑義が生じた場合には(ユーザーは、当社の定めるところに従うものとします。これにより解決しない場合には、)、当社およびユーザーは、信義誠実の原則に従って協議の上速やかに解決を図るものとします。</p>
<p>. 準拠および合意管轄</p>
<p> 本規約は日本法に準拠します。ユーザーは、本規約に関連する紛争については、福岡地方裁判所を第1審の専属的合意管轄裁判所とすることに同意するものとします。</p>
<h3><a id="user-content-第11条ユーザーの責任" class="anchor" href="#第11条ユーザーの責任" aria-hidden="true"><span class="octicon octicon-link"></span></a>第11条ユーザーの責任</h3>
<p>1ユーザーは、本サービスに有効にアカウント登録されている期間内に限り、本規約および当社の定めるところにしたがい、本サービスを利用することができます。</p>
<p>2 本サービスの提供を受けるために必要な、コンピューター、スマートフォンその他の機器、ソフトウェア、通信回線その他の通信環境等は、ユーザーの費用と責任において準備し維持するものとします。当社は、本サービスがあらゆる機器等に適合することを保証するものではありません。</p>
<p>3ユーザーは、自らの責任において本サービスを利用するものとし、本サービスにおいて行った一切の行為およびその結果について一切の責任を負うものとします。</p>
<p>4ユーザーが、当サービスを退会したユーザーのソースコードやapi等を複製・編集等の行為を行う場合は、自らの責任において行うものとし、本サービスにおいて行った一切の行為およびその結果について一切の責任を負うものとします。</p>
<p>5第三者が他のユーザーのメールアドレスやパスワードを使用し、そのユーザーに成りすまし、それが発覚した場合、成りすまし後投稿・編集したコンテンツに対して権利を主張する事はできません。その場合ユーザーと第三者との間でクレーム、トラブル、請求、紛争等以下、「クレーム等」といいます。が発生した場合、当該ユーザーと第三者は自己の費用と責任において当該問題等を解決し、且つ、当該損害等を賠償し、当社は一切の責任を負いません。</p>
<p>6ユーザーコンテンツに関して、第三者との間でクレーム等が生じ、又は第三者に損害等を与えた場合には、当該ユーザーは自己の費用と責任において当該クレーム等を解決し、かつ、当該損害等を賠償するものとし、当社は一切の責任を負わないものとします。その他本サービス上での、ユーザー間またはユーザーと第三者間での問題が発生した場合、当該ユーザーは自己の責任と費用において、問題を解決しなければならず、当社は一切の責任を負いません。</p>
<p>7本サービス上でユーザー自身が登録・公開した情報に関しては、当該ユーザーが自己の責任と費用において管理するものとし、当社は一切の責任を負いません。</p>
<p>8ユーザーが退会した後も、本サービス上でユーザー自身が登録・公開した情報に関しては、当該ユーザーが自己の責任に帰属するものとし、当社は一切の責任を負いません。</p>
<p>9ユーザーは、本サービスを利用したことに関連して、当社が直接的もしくは間接的に何らかの損害弁護士費用の負担を含みます。を被った場合当社がユーザーの利用を原因とする請求等を第三者より受けた場合を含みます。、当社の請求に従って直ちにこれを補償するものとします。</p>
<h3><a id="user-content-第12条免責事項" class="anchor" href="#第12条免責事項" aria-hidden="true"><span class="octicon octicon-link"></span></a>第12条免責事項</h3>
<p> 本サービスは開発中のものであり、その性質上、バグや瑕疵、誤動作など、正常に動作しない症状等の不具合を含み得るものとして提供され、当社はその正確性・完全性・有用性・信頼性・無害性等に関していかなる保証もいたしません。ユーザーのデータは、予告なく一部または全部削除されたり、当社からユーザーに対してデータ等の削除を要請する場合があります。当社は、バージョン変更によるアップデート後に提供されるCodeXenや他のサービスにおいてデータを引き継ぐ義務を負わないものとします。また、当社は、CodeXenのユーザーが自らのアカウントを削除した後も、そのユーザーが過去に投稿したコンテンツソースコードやコマンド、スニペット等を削除する義務は負わず、ユーザーは削除を要求する権利を持たない事に同意します。
 当社は、次に掲げる事由その他本サービスの利用により発生したユーザー、その他関係者の損害について、 損害発生の理由の如何を問わず(ユーザーのサービス利用能力の欠如に起因するもの、本サービスに対する不正アクセス・ハッキング・改竄等に起因するものも含む)、一切の責任を負いません。</p>
<p>1本サービスの利用、利用不能</p>
<p>2作為不作為、内容を問わず、本サービスの利用・アクセスによって生じた個人的損害、著作権その他知的財産権の侵害</p>
<p>3コンテンツの誤り、不正確性、エラー</p>
<p>4意図する意図しないに関わらず、ファイルの上書きや書き換え、またはそれに伴う操作において、元ファイルの復元が不可能な場合</p>
<p>5本サービスのサーバーもしくは蓄積された全ての個人情報に対する不正アクセス</p>
<p>6本サービスのトランザクションの遅延や中断</p>
<p>7第三者によって本サービスに仕組まれたウイルス、不正なプログラム、またはそれに類するもの</p>
<p>8本サービスへのアクセス・利用により生じるエラー、バグ、コンテンツの欠損・消失・変更・損失・損害</p>
<p>9第三者による中傷、攻撃、勧誘</p>
<p>10ユーザーによるパスワードおよびアカウント情報が通信過程で第三者に解読されたことによりアクセス権の秘密性を守れなかったこと</p>
<p>11天災等の不可抗力、予想外の技術的・セキュリティ上の問題、又は不正アクセス等によりシステムに重大な支障が生じたとき等のやむを得ない事由によって、本サービスの一部又は全部の提供が不可能になったとき</p>
<p>12法律や裁判所の命令によって個人情報の開示を命じられ、又は捜査当局の任意捜査若しくは法律上照会権限、 開示請求権を持つ者によって照会・開示を求められるなど他の優先する利益のために当社が個人情報を開示したこと</p>
<h3><a id="user-content-第13条ライセンスに関する条項" class="anchor" href="#第13条ライセンスに関する条項" aria-hidden="true"><span class="octicon octicon-link"></span></a>第13条ライセンスに関する条項</h3>
<p> ユーザーが当社の提供するソースコード、APIを販売、譲渡、またはサブライセンスすることはできません。</p>
<h3><a id="user-content-第14条サービス内容の変更等" class="anchor" href="#第14条サービス内容の変更等" aria-hidden="true"><span class="octicon octicon-link"></span></a>第14条サービス内容の変更等</h3>
<p> 当社は、ユーザーに通知することなく本サービスの内容・利用料金を変更し、または本サービスの提供を中止することができるものとし、これによってユーザーに生じた損害について一切の責任を負いません。</p>
<h3><a id="user-content-第15条利用規約の変更" class="anchor" href="#第15条利用規約の変更" aria-hidden="true"><span class="octicon octicon-link"></span></a>第15条利用規約の変更</h3>
<p> 当社は、必要と判断した場合には、ユーザの承諾を得ることなく、本規約を随時変更・改訂することができます。 また、変更・改訂後の本規約が、第15条一項に掲げる方法でユーザーへ通知・連絡を当社が行った時点以降に、ユーザーが当サイトにアクセスし、本サービスを利用される場合、変更・改訂後の利用規約に同意したものとみなされます。 変更・改訂後の本規約に同意頂けない場合は、当サイトへのアクセス、または本サービスをご利用頂くことは出来ません。</p>
<h3><a id="user-content-第16条個人情報の保護" class="anchor" href="#第16条個人情報の保護" aria-hidden="true"><span class="octicon octicon-link"></span></a>第16条個人情報の保護</h3>
<p> 当社は、<a href ng-click="vm.showPP()">プライバシー・ポリシー(リンク)</a>に従って、ユーザーの個人情報を適切に取り扱います。</p>
<p>以上</p>
<p>(平成27年5月22日制定)</p>
</div>
<div class="modal-footer">
<button ng-if="vm.isAgreement" ng-disabled="vm.check" ng-click="vm.submit()" type="button" class="btn btn-primary">同意する</button>
<button ng-if="vm.isAgreement" ng-click="vm.cancel()" type="button" name="button" class="btn btn-default">同意しない</button>
<button ng-if="!vm.isAgreement" ng-click="vm.cancel()" type="button" name="button" class="btn btn-default">Close</button>
</div>
</div>

View File

@@ -1,48 +0,0 @@
<div class="home-state">
<h1 class="jumbotron">Codexen App <small>v0.1.2</small></h1>
<h2>About CodeXen</h2>
<p>
CodeXen is short code storage tool make coding more stressless. If you use CodeXen, then you will be disentangled from troublesome organizing a large number of snippets and googling same code many times.
</p>
<ol>
<li>
<h4>
Post your code
</h4>
<p>
Post your commonly used code with description,category,and tags.
</p>
</li>
<li>
<h4>
Save on cloud
</h4>
<p>
From short snippet to long complex code,CodeXen saves any code simply.
</p>
</li>
<li>
<h4>
Use code like a magic
</h4>
<p>
CodeXen call code you posted whereever you are.Type [shift+control+tab] simultaneously.
</p>
</li>
<li>
<h4>
Code Elegantly
</h4>
<p>
That's all!
You must be loved with CodeXen. Enjoy coding;)
</p>
</li>
</ol>
<p>
© 2015 MAISIN&CO.,Inc.
</p>
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 463 B

After

Width:  |  Height:  |  Size: 959 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 924 B

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB